模拟自动执行的ExecutorService

时间:2015-12-04 20:47:56

标签: spring unit-testing mockito executorservice

摘要:

我有一个Spring @Component,它使用自动装配的ExecutorService作为工作池。我使用JUnit和Mockito来测试组件的功能,我需要模拟Executor服务。对于其他自动装配的成员来说这是微不足道的 - 一个通用助手,例如DAO层很容易被模拟,但我需要一个真正的执行者服务。

代码:

@RunWith(MockitoJUnitRunner.class)
public class MadeUpClassNameTest{

  @Mock
  private ExecutorService executor;

  @Before
  public void initExecutor() throws Exception{
      executor = Executors.newFixedThreadPool(2);
  }

  @InjectMocks
  private ASDF componentBeingAutowired;
...

仅此一项无效,invokeAll()的结果始终为空列表。

尝试更明确地模拟执行程序方法也不起作用......

@Test
public void myTestMethod(){
    when(executor.invokeAll(anyCollection()))
        .thenCallRealMethod();
    ...
}

我得到了隐藏的措辞异常:

  

您不能在验证或存根之外使用参数匹配器。

(我认为这是一个存根?)

可以提供thenReturn(Answer<>)方法,但是我想确保代码实际上与执行程序一起工作,相当多的代码专门用于映射期货的结果。

问题 如何提供真实(或功能可用的模拟)Executor服务?或者,我是否难以测试这个组件,这表明这是一个需要重构的糟糕设计,或者可能是一个糟糕的测试场景?

备注 我想强调一下,我的问题是没有让Mockito或Junit成立。其他模拟和测试工作正常。我的问题仅针对上面的特定模拟。

使用:Junit 4.12,Mockito 1.10.19,Hamcrest 1.3

3 个答案:

答案 0 :(得分:6)

I think the following code runs after the Mock is injected.

@Before
public void initExecutor() throws Exception{
  executor = Executors.newFixedThreadPool(2);
}

This causes your local copy of executor to be set, but not the one that is injected.

I would recommend using constructor injection in on your componentBeingAutowired and create a new one in your unit test and exclude Spring dependencies. Your test could then look like something below:

public class MadeUpClassNameTest {
    private ExecutorService executor;

    @Before
    public void initExecutor() throws Exception {
        executor = Executors.newFixedThreadPool(2);
    }

    @Test
    public void test() {
        ASDF componentBeingTested = new ASDF(executor);
        ... do tests
    }
}

答案 1 :(得分:0)

您可以使用@Spy注释。

@RunWith(MockitoJUnitRunner.class)
public class MadeUpClassNameTest{
@Spy
private final ExecutorService executor = Executors.newFixedThreadPool(2);

@Test
...
}

答案 2 :(得分:-1)

您可以使用@Spy注释。

@RunWith(MockitoJUnitRunner.class)
public class MadeUpClassNameTest{

    @Spy
    private final ExecutorService executor = Executors.newFixedThreadPool(2);

    ....

}