使用 EasyMock 测试简单的多线程代码但得到奇怪的结果
Testing simple multithread code using EasyMock but got strange result
我正在使用 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:
Expectation failure on verify:
TestObject.doSomething(): expected: 2, actual: 1
at org.easymock.internal.MocksControl.verify(MocksControl.java:225)
at 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: Expectation failure on verify:
TestObject.doSomething(): expected: 3, actual: 2
为什么我给它 2 结果却期待 3?
抱歉,我不是 EasyMock
方面的专家,如果有人能提供帮助,我将不胜感激。
没有什么能确保在达到 verify
之前执行您的任务。你需要一些东西来调整执行速度。
这个有效:
@测试
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
被捕获并忽略。
我正在使用 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:
Expectation failure on verify: TestObject.doSomething(): expected: 2, actual: 1 at org.easymock.internal.MocksControl.verify(MocksControl.java:225) at 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: Expectation failure on verify: TestObject.doSomething(): expected: 3, actual: 2
为什么我给它 2 结果却期待 3?
抱歉,我不是 EasyMock
方面的专家,如果有人能提供帮助,我将不胜感激。
没有什么能确保在达到 verify
之前执行您的任务。你需要一些东西来调整执行速度。
这个有效:
@测试 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
被捕获并忽略。