2017-01-09 14 views
0

を得た私は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); 
    } 
} 

Iこの場合、testObject.doSomething()は2回だけ呼び出されるべきだと思います。スレッドプールには1つのスレッドがあり、キューサイズは1であるため、最初に2つのスレッドをスリープさせます。だから3つの課題を提出すると、3つ目の課題は却下され、最初の2つは呼び出されるべきです。私はこのコード を実行するとエラーが発生した。しかし:

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; 
     }}); 

この時のエラーは次のようになります。私はそれを2を与えるとき

java.lang.AssertionError: Expectation failure on verify: TestObject.doSomething(): expected: 3, actual: 2

なぜ結果が3を期待していますか?

私はEasyMockの専門家ではありません。本当にありがとうございます。

答えて

1

verifyに達する前にタスクが実行されていることを確認するものはありません。あなたは実行をペースするために何かが必要です。

この作品:

@Test公共ボイドtest_easyMockTestは()InterruptedExceptionある{ たCountDownLatch(3)=新しいたCountDownLatchラッチスロー。

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がキャッチされ、無視されるようにしたいと仮定しています。

+0

はい、後で原因を調べます。 CountDownLatchを提案してくれてありがとう! – michael