在集成测试中覆盖Spring的@Configuration
在集成测试中覆盖Spring的@Configuration
我有一个类似这样的Spring Boot配置类:\n
@Configuration public class ClockConfiguration { @Bean public Clock getSystemClock() { return Clock.systemUTC(); } }
\n我有一些集成测试,如下所示:\n
@SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public abstract class AbstractIntegrationTest { }
\n以及像这样的测试:\n
public class MiscTests extends AbstractIntegrationTest{ @Test public void CreateSomethingThatOnlyWorksInThe Morning_ExpectCorrectResponse() { }
\n我想能够调整时钟bean以在一天的不同时间运行一些测试。我应该怎么做?\n注意:我看到了一些类似的stackoverflow答案,但我无法让它们起作用。\n根据其他答案,解决方案似乎应该是这样的:\n
@SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT) public abstract class AbstractIntegrationTest { @Configuration class MyTestConfiguration { @Bean public Clock getSystemClock() { Clock realClock = Clock.systemDefaultZone(); return Clock.offset(realClock, Duration.ofHours(9)); } } }
\n但是什么也没有发生。我需要@Import什么?我需要@Autowired什么吗?\n谢谢!
问题的原因是在集成测试中,需要覆盖Spring的@Configuration配置。解决方法是使用@TestConfiguration来覆盖@Configuration,并使用@MockBean来模拟需要覆盖的bean。
在Spring Boot中,可以使用@IntegrationTest注解来实现覆盖@Configuration的功能。首先,在抽象的集成测试类中使用@IntegrationTest注解来指定需要覆盖的@Configuration类和web环境。然后,可以在每个测试方法中使用@MockBean注解来模拟需要覆盖的bean的公共方法。
根据@MockBean注解的官方文档,任何已存在的相同类型的单例bean都将被模拟对象替代。
然而,需要注意的是,在使用@MockBean注解时,要确保注解的类型与需要覆盖或模拟的bean的类型一致。如果使用了错误的类型,可能会导致"java.lang.IllegalStateException: Failed to load ApplicationContext"错误。
需要注意的是,无法使用模拟框架直接覆盖@Configuration配置。要覆盖配置,需要使用@TestConfiguration注解。如果要使用模拟框架来模拟bean,需要模拟bean本身,而不是配置类。