2016-09-17 124 views
0

我正在使用spring启动项目,我们刚刚升级到版本1.4.0.RELEASE。作为版本升级的一部分,我们已经开始在抽象集成测试类中使用@SpringBootTest批注。在阅读the documentation后,听起来好像我们应该能够在特定测试期间使用嵌套的@ TestConfiguration注释的配置类来覆盖bean定义。这不适合我们,而是我们试图覆盖的非测试bean仍在使用中。有趣的是,似乎模拟测试bean和生产bean的用法实际上是在同一个测试中交织在一起的,就像两个bean在应用程序上下文中并排存在一样。此外,它看起来像集成测试以某种方式运行的顺序会影响此行为。我想知道这是我们配置错误还是有其他事情发生。嵌套配置不能按预期工作

编辑:

的抽象类,集成测试,从外观继承这样的:

@RunWith(SpringRunner.class) 
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT) 
@ActiveProfiles({"local", "test"}) 
public abstract class BaseIntegrationTest { 

    @Value("${local.server.port}") 
    protected int port; 
} 

,我们看到了奇怪的行为看起来像这样的集成测试:

public class WebhookProcessorIT extends BaseIntegrationTest { 

    @TestConfiguration 
    public static class Config { 
     @Bean 
     @Primary 
     public WebhookTask webhookTask() { 
      return mock(WebhookTask.class); 
     } 
    } 

    // sometimes the mock above is used and sometimes 
    // the actual production bean is used 
    @Autowired 
    private WebhookTask task; 

    @Before 
    public void setup() { 
     when(task.process(any())).thenReturn(true); 
    } 

    // tests ... 
} 

这就是根应用程序上下文类的样子:

@EnableAutoConfiguration(exclude = ErrorMvcAutoConfiguration.class) 
@SpringBootApplication 
public class Application { 
    private static final Logger log = LoggerFactory.getLogger(Application.class); 

    public static void main(String[] args) { 
     final SpringApplication app = new SpringApplication(Application.class); 
     app.setBannerMode(Banner.Mode.OFF); 
     app.run(args); 
    } 
} 

编辑:

我一直在使用@MockBean,像这样也试过:

public class WebhookProcessorIT extends BaseIntegrationTest { 

    @MockBean 
    private WebhookTask task; 

,但我得到了相同的结果测试运行时。我可以看到春天正试图在我的测试设置中查看日志覆盖生产豆与我所提供的模拟:

build 15-Sep-2016 09:09:24 2016-09-15 09:09:24 [34mINFO [0;39m [36m[DefaultListableBeanFactory][0;39m (main) Overriding bean definition for bean 'productionWebhookTask' with a different definition 

然而,当涉及到测试的执行,我仍然可以看到生产豆使用:

build 15-Sep-2016 09:09:29 2016-09-15 09:09:29 [39mDEBUG[0;39m [36m[WebhookSupplier][0;39m (WebhookProcessor) Received webhook with ID '1234' from queue. 
build 15-Sep-2016 09:09:30 2016-09-15 09:09:30 [39mDEBUG[0;39m [36m[WebhookSupplier][0;39m (WebhookProcessor) Received webhook with ID '5678' from queue. 
build 15-Sep-2016 09:09:30 2016-09-15 09:09:30 [39mDEBUG[0;39m [36m[ProductionWebhookTask][0;39m (WebhookProcessor) Received webhook with ID '1234' for processing // production webhook task bean still being used for webhook '1234' 
build 15-Sep-2016 09:09:30 2016-09-15 09:09:30 [39mDEBUG[0;39m [36m[WebhookSupplier][0;39m (WebhookProcessor) Deleting webhook with id '5678' from queue. // mock bean causes production logic to be skipped and we just delete webhook '5678' 
// More logs from production webhook task operating on webhook with id '1234' and causing the test to fail 
+0

你的意思是偶尔有真正的豆运行,而不是嘲笑一个还是什么? –

+0

您可以分享您的测试课程,以便我们可以更多地了解您的具体设置? –

+0

@ShadyRagab好像是这样。 – enbdk

回答

0

无论如何,你可以用@profile(“测试”)和你以假乱真与@profile(“生产”)

,然后在属性文件中注释您的测试豆把财产spring.profiles.active =测试

从文档

不同于常规@Configuration类使用@TestConfiguration 不能防止自动检测@SpringBootConfiguration的。

不像会被用来代替 应用程序的主要配置,嵌套@TestConfiguration 类将除了您的应用程序的主 配置中使用嵌套类@Configuration。

+0

我不想在这种情况下使用配置文件,因为我们有其他使用生产WebhookTask bean的集成测试,理想情况下我们希望能够使用嵌套配置将它仅存储在某些测试中。 – enbdk

+0

此外,我链接在我的问题文档的部分;) – enbdk

0

由于您使用的是Spring Boot 1.4版本。0,你可以继续使用新引入的注释@MockBean而不是使用不同的配置类来模拟原始bean。它非常简单,非常适合您的使用案例。

Here you go with an example from the documentation

+0

我也尝试使用MockBean注释,我得到了相同的结果。我已经更新了我的问题,并附上了一些评论。 – enbdk