被测试的类: Buffer.java

package test;

import java.util.HashMap;
import java.util.Map;


/**
 *
 * @author sting
 */
public class Buffer {
    private static Buffer me = new Buffer();
   
    public static Buffer getInstance() {
        return me;
    }
   
    private Map<String, Integer> buff;
   
    private Buffer() {
        this.buff = new HashMap<String, Integer>();
    }
   
    public void put(String key, int value) {
            if (!(this.buff.containsKey(key))) {
                this.buff.put(key, value);
        }
    }
   
    public int get(String key) {
            if (this.buff.containsKey(key)) {
                return this.buff.get(key);
            }
            return 0;
    }
}

TestCase: BufferTest.java
package test;

import net.sourceforge.groboutils.junit.v1.MultiThreadedTestRunner;
import net.sourceforge.groboutils.junit.v1.TestRunnable;
import junit.framework.TestCase;


/**
 *
 * @author sting
 */
public class BufferTest extends TestCase {
    private Buffer buff;
   
    protected void setUp() throws Exception {
        super.setUp();
        buff = Buffer.getInstance();
    }

    protected void tearDown() throws Exception {
        super.tearDown();
    }

    public void test() throws Throwable {
        TestRunnable[] runnables = new TestRunnable[] {
                new WriteToBuffer(buff, 10),
                new GetFromBuffer(buff, 10)
        };
       
        MultiThreadedTestRunner testRunner =
                new MultiThreadedTestRunner(runnables);
        testRunner.runTestRunnables();
    }
   
    private static class WriteToBuffer extends TestRunnable {
        private int value;
        private Buffer buff;
       
        public WriteToBuffer(Buffer buff, int value) {
            this.buff = buff;
            this.value = value;
        }
       
        @Override
        public void runTest() throws Throwable {
            buff.put("sting", value);
        }
    }
   
    private static class GetFromBuffer extends TestRunnable {
        private int value;
        private Buffer buff;
       
        public GetFromBuffer(Buffer buff, int value) {
            this.buff = buff;
            this.value = value;
        }
       
        @Override
        public void runTest() throws Throwable {
            assertEquals(value, buff.get("sting"));
        }
    }
}

运行该test case,结果如下:
WARN [Thread-1] (MultiThreadedTestRunner.java:276) - A test thread caused an exception.
junit.framework.AssertionFailedError: expected:<10> but was:<0>
    at junit.framework.Assert.fail(Assert.java:47)
    at junit.framework.Assert.failNotEquals(Assert.java:282)
    at junit.framework.Assert.assertEquals(Assert.java:64)
    at junit.framework.Assert.assertEquals(Assert.java:201)
    at junit.framework.Assert.assertEquals(Assert.java:207)
    at test.BufferTest$GetFromBuffer.runTest(BufferTest.java:75)
    at net.sourceforge.groboutils.junit.v1.TestRunnable.run(TestRunnable.java:154)
    at java.lang.Thread.run(Unknown Source)

把Buffer.java加上同步处理:
public class Buffer {
    private static Buffer me = new Buffer();
   
    public static Buffer getInstance() {
        return me;
    }
   
    private Map<String, Integer> buff;
   
    private Buffer() {
        this.buff = new HashMap<String, Integer>();
    }
   
    public void put(String key, int value) {
        synchronized (this) {
            if (!(this.buff.containsKey(key))) {
                this.buff.put(key, value);
            }
        }
    }
   
    public int get(String key) {
        synchronized (this) {
            if (this.buff.containsKey(key)) {
                return this.buff.get(key);
            }
            return 0;
        }
    }
}

测试通过。

这里只是用最简单的code演示了一下如何使用GroboUtils里面提供 TestRunnable和 MultiThreadedTestRunner来编写多线程的测试代码。其实也可以自己写code去测试,不过已经有人写了,不用再重复去做了。Please refer to http://broboutils.sourceforge.net to get more information.