【问题标题】:Testing simple multithread code using EasyMock but got strange result使用 EasyMock 测试简单的多线程代码但得到奇怪的结果
【发布时间】:2017-01-09 08:08:31
【问题描述】:

我正在使用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():预期:2,实际: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():预期:3,实际:2

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

抱歉,我不是 EasyMock 方面的专家,如果有人可以提供帮助,我将不胜感激。

【问题讨论】:

    标签: java multithreading easymock


    【解决方案1】:

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

    这行得通:

    @测试 公共 void test_easyMockTest() 抛出 InterruptedException { CountDownLatch 锁存器 = 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 被捕获和忽略。

    【讨论】:

    • 是的,我稍后会找出原因。感谢您推荐 CountDownLatch!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多