Spring、Spring Boot和TestNG测试指南 - @TestConfiguration

Github地址html

@TestConfiguration是Spring Boot Test提供的一种工具,用它咱们能够在通常的@Configuration以外补充测试专门用的Bean或者自定义的配置。java

@TestConfiguration其实是一种@TestComponent@TestComponent是另外一种@Component,在语义上用来指定某个Bean是专门用于测试的。git

须要特别注意,你应该使用一切办法避免在生产代码中自动扫描到@TestComponent
若是你使用@SpringBootApplication启动测试或者生产代码,@TestComponent会自动被排除掉,若是不是则须要像@SpringBootApplication同样添加TypeExcludeFiltergithub

//...
@ComponentScan(excludeFilters = {
  @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  // ...})
public @interface SpringBootApplication

例子1:做为内部类

@TestConfiguration和@Configuration不一样,它不会阻止@SpringBootTest去查找机制(在Chapter 1: 基本用法 - 使用Spring Boot Testing工具 - 例子4提到过),正如@TestConfiguration的javadoc所说,它只是对既有配置的一个补充。spring

因此咱们在测试代码上添加@SpringBootConfiguration,用@SpringBootTest(classes=...)或者在同package里添加@SpringBootConfiguration类都是能够的。api

并且@TestConfiguration做为内部类的时候它是会被@SpringBootTest扫描掉的,这点和@Configuration同样。app

测试代码TestConfigurationTestspring-boot

@SpringBootTest
@SpringBootConfiguration
public class TestConfigurationTest extends AbstractTestNGSpringContextTests {

  @Autowired
  private Foo foo;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getName(), "from test config");
  }

  @TestConfiguration
  public class TestConfig {

    @Bean
    public Foo foo() {
      return new Foo("from test config");
    }

  }
}

例子2:对@Configuration的补充和覆盖

@TestConfiguration可以:工具

  1. 补充额外的Bean测试

  2. 覆盖已存在的Bean

要特别注意第二点,@TestConfiguration可以直接覆盖已存在的Bean,这一点正常的@Configuration是作不到的。

咱们先提供了一个正常的@Configuration(Config):

@Configuration
public class Config {

  @Bean
  public Foo foo() {
    return new Foo("from config");
  }
}

又提供了一个@TestConfiguration,在里面覆盖了foo Bean,而且提供了foo2 Bean(TestConfig):

@TestConfiguration
public class TestConfig {

  // 这里不须要@Primary之类的机制,直接就可以覆盖
  @Bean
  public Foo foo() {
    return new Foo("from test config");
  }

  @Bean
  public Foo foo2() {
    return new Foo("from test config2");
  }
}

测试代码TestConfigurationTest

@SpringBootTest(classes = { Config.class, TestConfig.class })
public class TestConfigurationTest extends AbstractTestNGSpringContextTests {

  @Qualifier("foo")
  @Autowired
  private Foo foo;

  @Qualifier("foo2")
  @Autowired
  private Foo foo2;

  @Test
  public void testPlusCount() throws Exception {
    assertEquals(foo.getName(), "from test config");
    assertEquals(foo2.getName(), "from test config2");

  }

}

再查看输出的日志,就会发现Auto Configuration已经关闭。

例子3:避免@TestConfiguration被扫描到

在上面的这个例子里的TestConfig是会被@ComponentScan扫描到的,若是要避免被扫描到,在本文开头已经提到过了。

先来看一下没有作任何过滤的情形,咱们先提供了一个@SpringBootConfiguration(IncludeConfig):

@SpringBootConfiguration
@ComponentScan
public interface IncludeConfig {
}

而后有个测试代码引用了它(TestConfigIncludedTest):

@SpringBootTest(classes = IncludeConfig.class)
public class TestConfigIncludedTest extends AbstractTestNGSpringContextTests {

  @Autowired(required = false)
  private TestConfig testConfig;

  @Test
  public void testPlusCount() throws Exception {
    assertNotNull(testConfig);

  }

}

从这段代码能够看到TestConfig被加载了。

如今咱们使用TypeExcludeFilter来过滤@TestConfiguration(ExcludeConfig1):

@SpringBootConfiguration
@ComponentScan(excludeFilters = {
    @ComponentScan.Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class)
})
public interface ExcludeConfig1 {
}

再来看看结果(TestConfigExclude_1_Test):

@SpringBootTest(classes = ExcludeConfig1.class)
public class TestConfigExclude_1_Test extends AbstractTestNGSpringContextTests {

  @Autowired(required = false)
  private TestConfig testConfig;

  @Test
  public void test() throws Exception {
    assertNull(testConfig);

  }

}

还能够用@SpringBootApplication来排除TestConfigExcludeConfig2):

@SpringBootApplication
public interface ExcludeConfig2 {
}

看看结果(TestConfigExclude_2_Test):

@SpringBootTest(classes = ExcludeConfig2.class)
public class TestConfigExclude_2_Test extends AbstractTestNGSpringContextTests {

  @Autowired(required = false)
  private TestConfig testConfig;

  @Test
  public void testPlusCount() throws Exception {
    assertNull(testConfig);

  }

}

参考文档

相关文章
相关标签/搜索