摘要:
我有一个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
答案 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);
....
}