【问题标题】:Issue with Mockito and JpaRepositoryMockito 和 JpaRepository 的问题
【发布时间】:2018-03-13 16:52:41
【问题描述】:

我有一个要迁移到 Spring boot 2 的 Spring Boot 项目。 我使用旧版本进行的一些测试在新版本中失败。

这个问题很容易重现。

我创建了 2 个控制器。首先,我注入一个服务。在第二个中,我注入了一个 JpaRepository。

现在我为这两个控制器创建单元测试。 对于第二个控制器,我模拟了存储库。一切正常。 对于第一个控制器,我模拟了服务。测试失败。 它似乎在搜索注入存储库,而在此控制器中未使用它。

我创建了一个非常简单的项目来重现这种行为: https://github.com/YLombardi/mockito-spring-jpa-issue

是我的测试错误还是错误?

【问题讨论】:

    标签: spring spring-boot mockito spring-data-jpa


    【解决方案1】:

    我能够从您提供的 repo url 中重现该问题。如果您在运行ControllerAUnitTests 时注意到异常,它会说

    ...UnsatisfiedDependencyException: Error creating bean with name 'controllerB'...

    现在,当您为 ControllerA 运行测试时,为什么 spring 会尝试加载 controllerB bean?

    这是因为您使用的是SpringRunner 和默认mockMvc。它加载整个 spring 上下文,这意味着它将创建每个组件的 bean,包括 controllerB

    要创建controllerB 的bean,您需要有一个JpaRepo 的实例。因此,就像您在 ControllerAUnitTests 中创建 ServiceA 的模拟 bean 一样,您也需要为 JpaRepo 创建模拟 bean。

        @MockBean
        private ServiceA serviceA;
    
        // NOTE THIS BLOCK
        @MockBean
        private JpaRepo jpaRepo;
    
        @Test
        public void test() throws Exception {
            doReturn("a").when(serviceA).getAString();
            mockMvc.perform(get("/a"))
                    .andDo(print())
                    .andExpect(status().isOk())
                    // Test now runs but assert fails below, that you need to fix.
                    .andExpect(view().name("aview"))
                    .andExpect(content().string("a"));
        }
    

    【讨论】:

    • 所以我需要在每个测试类中模拟 JpaRepo 吗?即使它没有在控制器中使用。好像很奇怪在之前的 spring 版本中,我们只需要模拟在被测试的类中注入的组件。
    • 默认情况下MockMvc 会加载所有上下文。如果您只想为单个控制器创建上下文,请使用 MockMvcBuilders.standaloneSetup... 创建独立上下文。
    • "我们只需要模拟在被测试的类中注入的组件" - 当您使用MockitoJunitRunner 运行测试时为真.
    • 谢谢,我理解我的错误。新注解@WebMvcTest 不替代需要配置MockMvcBuilders.standaloneSetup(controllerA).build();
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2014-11-16
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多