在单元测试中覆盖自动装配的Bean

sam*_*ake 49 spring spring-annotations spring-boot

有一种简单的方法可以在特定的单元测试中轻松覆盖自动装配的bean吗?在编译类中只有一个类型的bean,因此在这种情况下自动装配不是问题.测试类将包含额外的模拟.在运行单元测试时,我只想指定一个额外的配置,基本上说,运行此使用测试时使用此模拟而不是标准bean.

对于我需要的内容,配置文件看起来有点矫枉过正,我不确定使用Primary注释可以实现这一点,因为不同的单元测试可能有不同的模拟.

teo*_*teo 73

如果您只是想在测试中提供不同的bean,我认为您不需要使用spring profile或mockito.

只需执行以下操作:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { TestConfig.class })
public class MyTest
{
    @Configuration
    @Import(Application.class) // the actual configuration
    public static class TestConfig
    {
        @Bean
        public IMyService myService()
        {
            return new MockedMyService();
        }
    }

    @Test
    public void test()
    {
        ....
    }
}
Run Code Online (Sandbox Code Playgroud)

注意:使用弹簧靴1.3.2 /弹簧4.2.4进行测试

  • 我得到了"bean的定义......已经存在.这个顶级bean定义被认为是一个覆盖." 我不得不将"myService()"方法更改为其他名称,例如"myServiceMock()".我还建议使用@Primary注释(用于IMyService)以确保TestConfig配置中定义的bean将覆盖Application配置中的bean. (9认同)
  • @Kacper86:添加"主要"注释解决了Spring关于找到2个接口实现的抱怨.谢谢! (4认同)
  • 我还必须使用`@ Primary`批注来覆盖原始bean(spring-boot-starter-parent:2.0.0.RELEASE,spring-boot-starter-test:2.0.4.RELEASE); thx @ Kacper86 (2认同)

Ser*_*kov 44

在Spring Boot 1.4中,有一种简单的方法:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = { MyApplication.class })
public class MyTests {
    @MockBean
    private MyBeanClass myTestBean;

    @Before
    public void setup() {
         ...
         when(myTestBean.doSomething()).thenReturn(someResult);
    }

    @Test
    public void test() {
         // MyBeanClass bean is replaced with myTestBean in the ApplicationContext here
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 什么是"MyApplication"? (3认同)
  • 如果你想用Mockito mock替换bean,这是最好的答案.否则(例如,如果你想注入一个自定义对象)它没有帮助. (2认同)
  • 要使“@MockBean”工作,您需要“@TestExecutionListeners(MockitoTestExecutionListener.class)”。其他一些注释或配置可以神奇地为您做到这一点。检查文档)) (2认同)

Isr*_*dez 6

我遇到了类似的问题,我混合使用解决了这一问题,我发现此方法更有用且可重复使用。我为测试创建了一个弹簧配置文件,并为配置类创建了一个配置类,该类以非常简单的方式覆盖了我想模拟的bean:

@Profile("test")
@Configuration
@Import(ApplicationConfiguration.class)
public class ConfigurationTests {

    @MockBean
    private Producer kafkaProducer;

    @MockBean
    private SlackNotifier slackNotifier;

}
Run Code Online (Sandbox Code Playgroud)

通过这样做,我可以@Autowire那些模拟豆,并使用模仿来验证它们。主要优势在于,现在所有测试都可以无缝获取模拟bean,而无需进行每次测试更改。经过测试:

弹簧靴1.4.2


Kir*_*ill 5

自 Spring Boot 1.4.0 起,无需显式指定@Configuration测试,只需添加带注释的静态嵌套类并提供带注释的@TestConfiguration替换@Bean@Primary

@TestConfiguration将被添加到您的主要 Spring Boot 测试上下文中(这意味着您的生产 bean 仍将被创建),但将使用来自的那个@TestConfiguration,因为@Primary.