【问题标题】:Spring Boot Test - Mocking A Handler Bean That Is Placed Deep In The Chain Of ResponsibilitySpring Boot 测试 - 模拟位于责任链深处的处理程序 Bean
【发布时间】:2018-10-23 12:37:24
【问题描述】:

这应该经常发生:

RestController -> SomeClass -> SomeOtherClass -> YetAnotherClass等等……

在我的具体情况下,有一个责任链被注入到休息控制器。每个类都被注入到上面链中的前一个类中。

我已经用 spring boot 实现了这个,我正在尝试测试 REST 资源。我想模拟 "YetAnotherClass" 以便当我使用 MockMvc 发送请求时,我可以验证模拟对象中是否发生了某些事情。

问题是,如果我使用 @MockBean 来模拟 YetAnotherClass,那么我必须将其注入到 SomeOtherClass。我试图用 @TestConfiguration 注入它,但是当请求通过 MockMvc 发送并且模拟对象嵌套在上面的链中深处时,模拟对象注入似乎不起作用. (注入的是原始 bean,而不是 mock 的)

我知道 JMockit 会模拟类的每个实例,因此它可以解决我的问题。但是 Spring boot 默认使用 Mockito,我更愿意避免不一致。

如何实现这样的测试场景?

【问题讨论】:

    标签: spring spring-boot mockito


    【解决方案1】:

    在设置Spring JUnit 文本装置时,我遇到了很多使用Mockito 的注释配置设置的烦恼。

    我发现我喜欢使用像这样的外部集成来模拟 bean 的方式是通过基本上使用标准 Spring 上下文配置为我想要的模拟对象创建一个单独的 MockObjectsConfig 类,然后将它与我的真实测试配置一起导入:

    @Configuration
    public class MockObjectsConfig {
    
        @Bean
        public YetAnotherClass yetAnotherClass() {
            Mockito.mock(YetAnotherClass.class); // and add any thenReturns, answers, etc. here
        }
    
        ... More mock beans...
    
    }
    

    然后像这样将它包含在您的测试中:

    @RunWith(SpringRunner.class)
    @ContextConfiguration(classes = { MyRealConfigClass.class, MockObjectsConfig.class)
    public class MyJunitTest {
    
        @Autowired
        private RestController restController;
    
    }
    

    如果需要防止出现冲突,您还可以使用 @Profile 注释您的模拟 bean 并使用 @ActiveProfiles 进行测试。

    这样,您的模拟 YetAnotherClass 将像所有其他 bean 一样被注入到您的上下文中 - 无需依赖、混合和摆弄 Mockito 和其他库注释。

    【讨论】:

    • 谢谢。似乎是个好主意。试一试,当测试变绿时接受。
    • 好的,如果您有更多问题,我们很乐意为您提供帮助
    • @Dovmo 如果您在 MyJunitTest 的测试中更改 YetAnotherClass 的 thenReturns 怎么办?甚至可能吗?我很好奇人们如何处理这些情况
    猜你喜欢
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-07-22
    相关资源
    最近更新 更多