【问题标题】:Overriding spring @Configuration in an integration test在集成测试中覆盖spring @Configuration
【发布时间】:2019-10-31 10:14:27
【问题描述】:

我有一个这样的spring boot配置类:

@Configuration
public class ClockConfiguration {

    @Bean
    public Clock getSystemClock() {
        return Clock.systemUTC();
    }
}

我有一些这样的集成测试:

@SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
public abstract class AbstractIntegrationTest  {

}

和这样的测试:

public class MiscTests extends AbstractIntegrationTest{

    @Test
    public void CreateSomethingThatOnlyWorksInThe Morning_ExpectCorrectResponse() {

    }

我希望能够偏移时钟 bean 以在一天的不同时间运行一些测试。我该怎么做?

注意:我看到 several stack overflow answers 与此类似,但我无法让它们工作。

根据其他回复,解决方案似乎应该是这样的:

@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));
        }
    }
}

但是那里什么也没有发生。我需要@Import 吗?我需要@Autowired 吗?

谢谢!

【问题讨论】:

    标签: java spring-boot integration-testing


    【解决方案1】:

    当您使用 Spring Boot 时,您可以利用 @MockBean 注释:

    @SpringBootTest(classes = MyApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
    public abstract class AbstractIntegrationTest  {
    
        @MockBean
        private Clock clockMock;
    }
    

    然后,您可以相应且唯一地为每个测试存根该 bean 的公共方法:

    @Test
    public void CreateSomethingThatOnlyWorksInThe Morning_ExpectCorrectResponse() {
         when(clockMock.getTime()).thenReturn(..);
    }
    

    根据@MockBean的javadoc:

    上下文中定义的任何现有的相同类型的单个 bean 将 被模拟替换。

    【讨论】:

    • 嗯,我很困惑。当你说: {at}MockBean private Clock clockMock;你的意思是:{at}MockBean public ClockConfiguration mockClock;请记住,我要覆盖(或模拟)的类称为“ClockConfiguration”。无论如何,当我添加我认为你的意思时,我收到了这个错误:“java.lang.IllegalStateException: Failed to load ApplicationContext”
    • @user952342 你不能用模拟框架过度配置。要覆盖配置,您需要 Testconfiguration 。如果你使用 Mock,你需要 Mock the Clock,而不是配置。
    【解决方案2】:

    你需要的是@TestConfiguration注解https://docs.spring.io/spring-boot/docs/current/api/org/springframework/boot/test/context/TestConfiguration.html

    @RunWith(SpringRunner.class)
    public class ClockServiceImplIntegrationTest {
    
        @TestConfiguration
        static class TestOverridingClockServiceConfiguration {
    
            @Bean
            public ClockService clockService() {
                return new ClockServiceImpl();
            }
        }
    
        @Autowired
        private ClockService clockService;
    
        @MockBean
        private ClockRepository clockRepository;
    
        // write test cases here
    }
    

    如果你有现有的配置,你可以 c

    【讨论】:

      猜你喜欢
      • 2019-08-20
      • 2016-06-15
      • 2017-11-22
      • 1970-01-01
      • 1970-01-01
      • 2018-11-09
      • 2014-12-25
      • 2018-04-04
      • 1970-01-01
      相关资源
      最近更新 更多