Spring Mockito和JpaRepository的问题

Spring Mockito和JpaRepository的问题,spring,spring-boot,mockito,spring-data-jpa,Spring,Spring Boot,Mockito,Spring Data Jpa,我有一个SpringBoot项目,我正在迁移到SpringBoot2。 我的一些测试表明,在使用旧版本时,在使用新版本时失败 这个问题很容易重现 我创建了2个控制器。首先,我注入一个服务。在第二个例子中,我注入了一个JpaRepository 现在我为这两个控制器创建单元测试。 对于第二个控制器,我模拟存储库。一切正常。 对于第一个控制器,我模拟服务。测试失败了。 它似乎在搜索以注入存储库,而此控制器中没有使用它 我创建了一个非常简单的项目来重现这种行为: 是我的测试错了还是一个bug?我能够

我有一个SpringBoot项目,我正在迁移到SpringBoot2。 我的一些测试表明,在使用旧版本时,在使用新版本时失败

这个问题很容易重现

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

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

我创建了一个非常简单的项目来重现这种行为:


是我的测试错了还是一个bug?

我能够从您提供的回购url中重现问题。如果在运行
ControllerAUnitTests
时注意到异常,则会显示

…未满足的PendencyException:创建名为“controllerB”的bean时出错…

现在,当您运行
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())的需要;