【问题标题】:TooManyActualInvocations exception when creating @Nested tests in @WebMvcTest在 @WebMvcTest 中创建 @Nested 测试时出现 TooManyActualInvocations 异常
【发布时间】:2020-10-16 07:34:34
【问题描述】:

我正在尝试使用 @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-mvc mockito junit5 spring-test-mvc


    【解决方案1】:

    Spring 测试支持不适用于嵌套测试,除非您在所有嵌套测试类中重复所有与 Spring 相关的注释。在这种情况下,我建议放弃嵌套。

    【讨论】:

    • 我不确定他们是否记录了一些不起作用的东西,即缺少的功能,但我在实现 github.com/jlink/jqwik-spring 时深入研究了 Spring 代码。您要么复制(大部分)嵌套类中的注释,要么它不起作用。 github.com/jlink/jqwik-spring 中的缺点部分适用于 Jupiter 和 jqwik 集成。
    【解决方案2】:

    这是 Spring Boot 中的一个开放错误:@MockBean fields are not reset for JUnit 5 @Nested tests #12470。

    它被 Spring Framework 中的另一个问题阻止:Discover test configuration on enclosing class for nested test class [SPR-15366] #19930

    后者计划为 5.3 M2,所以希望这不会很快成为问题。

    【讨论】:

      猜你喜欢
      • 2018-08-03
      • 2019-03-11
      • 2021-12-30
      • 2015-11-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-02-17
      • 1970-01-01
      相关资源
      最近更新 更多