使用EasyMock测试简单的多线程代码但得到了奇怪的结果

时间:2017-01-09 08:08:31

标签: java multithreading easymock

我正在使用EasyMock测试一个简单的多线程代码:

源代码:

public class EasyMockTest {

    ExecutorService executorService;
    TestObject testObject;

    public EasyMockTest(ExecutorService executorService, TestObject testObject)
    {
        this.executorService = executorService;
        this.testObject = testObject;
    }
    public void test()
    {
        try
        {
            executorService.submit(() ->{
                testObject.doSomething(); 
            });
        }
        catch(RejectedExecutionException ex)
        {
        }
     }
}


public class TestObject {

    public void doSomething()
    {
    }
}

使用EasyMock测试代码:

public class EasyMockTest_test {

    private TestObject testObject;
    private ExecutorService executorService;
    private EasyMockTest easyMockTest;

    @Before
    public void setUp()
    {
        executorService = new ThreadPoolExecutor(1, 1, 60, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(1));
        testObject = EasyMock.createMock(TestObject.class);
        easyMockTest = new EasyMockTest(executorService, testObject);
    }

    @Test
    public void test_easyMockTest()
    {
        testObject.doSomething(); 
        EasyMock.expectLastCall().andAnswer(new IAnswer<Void>(){
            @Override
            public Void answer() throws Throwable {
                Thread.sleep(100);
                return null;
            }}).times(2);

        EasyMock.replay(testObject);
        easyMockTest.test();
        easyMockTest.test();
        easyMockTest.test();

        EasyMock.verify(testObject);
    }
}

我认为在这种情况下testObject.doSomething()应该只被调用两次。由于线程池有一个线程,队列大小是一个,我让前两个线程休眠。因此,当我提交三个任务时,应该拒绝第三个任务,并且应该调用前两个任务。但是当我运行这段代码时 有错误:

  

java.lang.AssertionError:
      验证期望失败:           TestObject.doSomething():expected:2,actual:1         在org.easymock.internal.MocksControl.verify(MocksControl.java:225)         在org.easymock.EasyMock.verify(EasyMock.java:2007)         ...

这意味着该方法只被调用一次,我无法理解。

我也试过评论Thread.sleep(100);这一次实际的通话时间变为2,但我认为它应该是3,因为没有线程正在睡觉。

然后我尝试移动.times()这样的位置:

EasyMock.expectLastCall().times(2).andAnswer(new IAnswer<Void>(){
        @Override
        public Void answer() throws Throwable {
            Thread.sleep(100);
            return null;
        }});

此时间错误变为:

  

java.lang.AssertionError:验证时出现预期失败:       TestObject.doSomething():expected:3,actual:2

为什么当我给它2时,结果是期待3?

抱歉,我不是EasyMock的专家,非常感谢有人可以提供帮助。

1 个答案:

答案 0 :(得分:1)

在达到verify之前,没有任何事情可以确保您的任务得以执行。你需要一些东西来加快执行速度。

这有效:

@Test   public void test_easyMockTest()抛出InterruptedException {     CountDownLatch latch = new CountDownLatch(3);

testObject.doSomething();
EasyMock.expectLastCall().andAnswer(new IAnswer<Void>(){
  @Override
  public Void answer() throws Throwable {
    latch.countDown();
    return null;
  }}).times(2);

EasyMock.replay(testObject);
easyMockTest.test();
easyMockTest.test();
easyMockTest.test();

latch.await(1, TimeUnit.SECONDS);

EasyMock.verify(testObject);

}

在这里,我假设你真的想要抓住并忽略RejectedExecutionException