在@WebMvcTest 中创建@Nested 测试时出现 TooManyActualInvocations 异常
TooManyActualInvocations exception when creating @Nested tests in @WebMvcTest
我正在尝试使用 @Nested 在 @WebMvcTest 中对我的测试进行分组,但不幸的是,我的一些测试表明失败并出现 TooManyActualInvocations 异常。
这是我得出的最小示例:
测试:
@WebMvcTest(value = AController.class)
public class AControllerMvcTest {
@MockBean
BService bService;
@Autowired
MockMvc mockMvc;
@Nested
class NestedTests1 {
@Test
void testOne() throws Exception {
System.out.println("Test One started");
Mockito.when(bService.getDummyString()).thenReturn("dummyResp1");
mockMvc.perform(MockMvcRequestBuilders.post("/underTest"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(bService).getDummyString();
System.out.println("Test One finished");
}
}
@Nested
class NestedTests2 {
@Test
void testTwo() throws Exception {
System.out.println("Test Two started");
System.out.println(bService.hashCode());
Mockito.when(bService.getDummyString()).thenReturn("dummyResp2");
mockMvc.perform(MockMvcRequestBuilders.post("/underTest"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(bService).getDummyString();
System.out.println("Test Two finished");
}
}
}
控制器:
@Controller
class AController {
final BService bService;
@Autowired
AController(BService bService) {
this.bService = bService;
}
@PostMapping("/underTest")
String methodUnderTest() {
return bService.getDummyString();
}
}
B服务:
@Service
class BService {
String getDummyString() {
return "ABC";
}
}
我收到的异常:
org.mockito.exceptions.verification.TooManyActualInvocations:
mypackage.controller.BService#0 bean.getDummyString();
Wanted 1 time:
-> at mypackage.controller.AControllerMvcTest$NestedTests1.testOne(AControllerMvcTest.java:45)
But was 2 times:
-> at mypackage.controller.AController.methodUnderTest(AController.java:19)
-> at mypackage.controller.AController.methodUnderTest(AController.java:19)
如果没有嵌套测试,相同的测试通过。
两种情况(嵌套测试和无嵌套测试)
- 测试按顺序执行(打印到控制台)
- bService 在两个测试中是相同的实例(使用调试器检查)
我的问题
- 为什么添加@Nested 导致我的测试失败
- 如何解决?
Spring 测试支持不适用于嵌套测试,除非您在所有嵌套测试 类 中重复所有 spring 相关注释。我建议在这种情况下放弃嵌套。
这是 Spring 引导中的一个未解决的错误:@MockBean fields are not reset for JUnit 5 @Nested tests #12470。
它被 Spring 框架中的另一个问题阻止:Discover test configuration on enclosing class for nested test class [SPR-15366] #19930
后者计划用于 5.3 M2,所以希望这不会很快成为问题。
我正在尝试使用 @Nested 在 @WebMvcTest 中对我的测试进行分组,但不幸的是,我的一些测试表明失败并出现 TooManyActualInvocations 异常。
这是我得出的最小示例:
测试:
@WebMvcTest(value = AController.class)
public class AControllerMvcTest {
@MockBean
BService bService;
@Autowired
MockMvc mockMvc;
@Nested
class NestedTests1 {
@Test
void testOne() throws Exception {
System.out.println("Test One started");
Mockito.when(bService.getDummyString()).thenReturn("dummyResp1");
mockMvc.perform(MockMvcRequestBuilders.post("/underTest"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(bService).getDummyString();
System.out.println("Test One finished");
}
}
@Nested
class NestedTests2 {
@Test
void testTwo() throws Exception {
System.out.println("Test Two started");
System.out.println(bService.hashCode());
Mockito.when(bService.getDummyString()).thenReturn("dummyResp2");
mockMvc.perform(MockMvcRequestBuilders.post("/underTest"))
.andExpect(MockMvcResultMatchers.status().isOk());
Mockito.verify(bService).getDummyString();
System.out.println("Test Two finished");
}
}
}
控制器:
@Controller
class AController {
final BService bService;
@Autowired
AController(BService bService) {
this.bService = bService;
}
@PostMapping("/underTest")
String methodUnderTest() {
return bService.getDummyString();
}
}
B服务:
@Service
class BService {
String getDummyString() {
return "ABC";
}
}
我收到的异常:
org.mockito.exceptions.verification.TooManyActualInvocations:
mypackage.controller.BService#0 bean.getDummyString();
Wanted 1 time:
-> at mypackage.controller.AControllerMvcTest$NestedTests1.testOne(AControllerMvcTest.java:45)
But was 2 times:
-> at mypackage.controller.AController.methodUnderTest(AController.java:19)
-> at mypackage.controller.AController.methodUnderTest(AController.java:19)
如果没有嵌套测试,相同的测试通过。
两种情况(嵌套测试和无嵌套测试)
- 测试按顺序执行(打印到控制台)
- bService 在两个测试中是相同的实例(使用调试器检查)
我的问题
- 为什么添加@Nested 导致我的测试失败
- 如何解决?
Spring 测试支持不适用于嵌套测试,除非您在所有嵌套测试 类 中重复所有 spring 相关注释。我建议在这种情况下放弃嵌套。
这是 Spring 引导中的一个未解决的错误:@MockBean fields are not reset for JUnit 5 @Nested tests #12470。
它被 Spring 框架中的另一个问题阻止:Discover test configuration on enclosing class for nested test class [SPR-15366] #19930
后者计划用于 5.3 M2,所以希望这不会很快成为问题。