使用嵌套的TestConfiguration覆盖Spring Boot 2.1 Slice测试中的bean

时间:2019-08-08 17:34:56

标签: java spring spring-boot

我刚刚将应用程序从Spring Boot 1.x迁移到2.1。我的测试之一由于bean overriding default

的更改而失败

我尝试将spring.main.allow-bean-definition-overriding设置为true,但是它不起作用。

您可以使用以下课程重现该问题:

@Configuration
public class ClockConfig {

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

}

@Service
public class MyService {

    private final Clock clock;

    public MyService(Clock clock) {
        this.clock = clock;
    }

    public Instant now() {
        return clock.instant();
    }

}

@RestController
public class MyResource {

    private final MyService myService;

    public MyResource(MyService myService) {
        this.myService = myService;
    }

    @GetMapping
    public ResponseEntity<Instant> now() {
        return ResponseEntity.ok(myService.now());
    }
}

测试失败。 clock()方法在Spring Boot 2.1中从未调用过,而在Spring Boot 1.5或Spring Boot 2.0中却从未调用过。

@RunWith(SpringRunner.class)
@WebMvcTest(MyResource.class)
@ContextConfiguration(classes = MyService.class)
public class ResourceTest {

    @Autowired
    private MockMvc mvc;

    @Test
    public void test() {
    }

    @TestConfiguration
    static class TestConfig {
        @Bean
        public Clock clock() {
            return Clock.fixed(Instant.MIN, ZoneId.of("Z"));
        }
    }
}

1 个答案:

答案 0 :(得分:0)

尝试修改ContextConfiguration批注。应该是:@ContextConfiguration(classes = {MyService.class,ClockConfig.class})。 您使用@ContextConfiguration注释明确指定了要导入测试的配置,因此根本不会加载@TestConfiguration。如果您排除@ContextConfiguration,则可以使用。由于您删除了MyService的配置,因此必须在测试配置中提供MyService bean。试试这个:

@RunWith(SpringRunner.class)
@WebMvcTest(MyResource.class)
public class DemoApplicationTests {

   @Autowired
   private MockMvc mvc;

   @Test
   public void test() {
   }

   @TestConfiguration
   static class TestConfig {
       @Bean
       public Clock clock() {
           return Clock.fixed(Instant.MIN, ZoneId.of("Z"));
       }

       @Bean
       public MyService service() {
           return new MyService(clock());
       }
   }
  }