我使用弹簧启动的@MockBean
(带@RunWith(SpringRunner.class)
),到目前为止一切都很好。
但是,模拟为模拟类的每个方法提供默认实现,因此我无法检查是否只调用了我希望被调用的那些方法,即我想创建严格的模拟。@MockBean
可能吗?
如果有人知道如何检查是否只调用了我期望的那些方法,我不会坚持创建严格的模拟。
提前感谢您的帮助!
问候
V.
使用 Mockito,您可以验证是否调用了方法:
verify(mockOne).add("one");
或者它从未被调用过(never() 是 times(0) 的更易读的别名):
verify(mockOne, never()).remove("two");
或者,您可以验证是否未调用其他方法:
verify(mockOne).add("one"); // check this one
verifyNoMoreInteractions(mockOne); // and nothing else
有关更多信息,请参阅 Mockito 文档。
你可以对@Mockbean创建的模拟对象使用 Mockito.verify 方法。它可以检查它调用了多少次、指定的参数等等。请尝试一下。
这是一种方法(相当复杂 - 最好只是等待 Mockito 4,其中默认将是严格的模拟,或者等到测试完成后使用模拟,然后使用 verifyNoMoreInteractins )
-
将@MockBean替换为@Autowired替换为带有@Primary的测试配置
-
创建一个默认答案,为任何未存根函数引发异常
然后用一些存根覆盖该答案 - 但你必须使用 doReturn 而不是 thenReturn
// this is the component to mock
@Component
class ExtService {
int f1(String a) {
return 777;
}
}
// this is the test class
@SpringBootTest
@RunWith(SpringRunner.class)
public class ApplicationTests {
static class RuntimeExceptionAnswer implements Answer<Object> {
@Override
public Object answer(InvocationOnMock invocation) throws Throwable {
throw new RuntimeException(
invocation.getMethod().getName() + " was not stubbed with the received arguments");
}
}
@TestConfiguration
public static class TestConfig {
@Bean
@Primary
public ExtService mockExtService() {
ExtService std = Mockito.mock(ExtService.class, new RuntimeExceptionAnswer());
return std;
}
}
// @MockBean ExtService extService;
@Autowired
ExtService extService; // replace mockBean
@Test
public void contextLoads() {
Mockito.doReturn(1).when(extService).f1("abc"); // stubbing has to be in this format
System.out.println(extService.f1("abc")); // returns 1
System.out.println(extService.f1("abcd")); // throws exception
}
}