Spring、Spring Boot和TestNG测试指南 ( 3 )

发表于:2017-12-11 11:34

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:chanjarster    来源:ImportNew

分享:
  测试代码JsonComponentJsonTest:
@SpringBootTest(classes = { JsonComponentJacksonTest.class, FooJsonComponent.class })
@JsonTest
public class JsonComponentJacksonTest extends AbstractTestNGSpringContextTests {
@Autowired
private JacksonTester<Foo> json;
@Test
public void testSerialize() throws Exception {
Foo details = new Foo("Honda", 12);
assertThat(this.json.write(details).getJson()).isEqualTo("\"name=Honda,age=12\"");
}
@Test
public void testDeserialize() throws Exception {
String content = "\"name=Ford,age=13\"";
Foo actual = this.json.parseObject(content);
assertThat(actual).isEqualTo(new Foo("Ford", 13));
assertThat(actual.getName()).isEqualTo("Ford");
assertThat(actual.getAge()).isEqualTo(13);
}
}
  例子3: 使用@ContextConfiguration
  事实上@JsonTest也可以配合@ContextConfiguration一起使用。
  源代码见ThinJsonTest:
@JsonTest
@ContextConfiguration(classes = JsonTest.class)
public class ThinJsonTest extends AbstractTestNGSpringContextTests {
@Autowired
private JacksonTester<Foo> json;
@Test
public void testSerialize() throws Exception {
// ...
}
@Test
public void testDeserialize() throws Exception {
// ...
}
}
@OverrideAutoConfiguration
  在 Spring、Spring Boot 和 TestNG 测试指南 ( 1 ) 提到:
  除了单元测试(不需要初始化ApplicationContext的测试)外,尽量将测试配置和生产配置保持一致。比如如果生产配置里启用了AutoConfiguration,那么测试配置也应该启用。因为只有这样才能够在测试环境下发现生产环境的问题,也避免出现一些因为配置不同导致的奇怪问题。
  那么当我们想在测试代码里关闭Auto Configuration如何处理?
  方法1:提供另一套测试配置
  方法2:使用@OverrideAutoConfiguration
  方法1虽然能够很好的解决问题,但是比较麻烦。而方法2则能够不改变原有配置、不提供新的配置的情况下,就能够关闭Auto Configuration。
  在本章节的例子里,我们自己做了一个Auto Configuration类,AutoConfigurationEnableLogger:
  @Configuration
  public class AutoConfigurationEnableLogger {
  private static final Logger LOGGER = LoggerFactory.getLogger(AutoConfigurationEnableLogger.class);
  public AutoConfigurationEnableLogger() {
  LOGGER.info("Auto Configuration Enabled");
  }
  }
  并且在META-INF/spring.factories里注册了它:
  org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
  me.chanjar.annotation.overrideac.AutoConfigurationEnableLogger
  这样一来,只要Spring Boot启动了Auto Configuration就会打印出日志:
  2017-08-24 16:44:52.789  INFO 13212 --- [           main] m.c.a.o.AutoConfigurationEnableLogger    : Auto Configuration Enabled
  例子1:未关闭Auto Configuration
  源代码见BootTest:
  @SpringBootTest
  @SpringBootApplication
  public class BootTest extends AbstractTestNGSpringContextTests {
  @Test
  public void testName() throws Exception {
  }
  }
  查看输出的日志,会发现Auto Configuration已经启用。
  例子2:关闭Auto Configuration
  然后我们用@OverrideAutoConfiguration关闭了Auto Configuration。
  源代码见BootTest:
  @SpringBootTest
  @OverrideAutoConfiguration(enabled = false)
  @SpringBootApplication
  public class BootTest extends AbstractTestNGSpringContextTests {
  @Test
  public void testName() throws Exception {
  }
  }
  再查看输出的日志,就会发现Auto Configuration已经关闭。
  @TestConfiguration
  @TestConfiguration是Spring Boot Test提供的一种工具,用它我们可以在一般的@Configuration之外补充测试专门用的Bean或者自定义的配置。
  @TestConfiguration实际上是一种@TestComponent,@TestComponent是另一种@Component,在语义上用来指定某个Bean是专门用于测试的。
  需要特别注意,你应该使用一切办法避免在生产代码中自动扫描到@TestComponent。 如果你使用@SpringBootApplication启动测试或者生产代码,@TestComponent会自动被排除掉,如果不是则需要像@SpringBootApplication一样添加TypeExcludeFilter:
  //...
  @ComponentScan(excludeFilters = {
  @Filter(type = FilterType.CUSTOM, classes = TypeExcludeFilter.class),
  // ...})
  public @interface SpringBootApplication
  例子1:作为内部类
  @TestConfiguration和@Configuration不同,它不会阻止@SpringBootTest去查找机制(在Chapter 1: 基本用法 – 使用Spring Boot Testing工具 – 例子4提到过),正如@TestConfiguration的javadoc所说,它只是对既有配置的一个补充。
  所以我们在测试代码上添加@SpringBootConfiguration,用@SpringBootTest(classes=…)或者在同package里添加@SpringBootConfiguration类都是可以的。
  而且@TestConfiguration作为内部类的时候它是会被@SpringBootTest扫描掉的,这点和@Configuration一样。
  测试代码TestConfigurationTest:
@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能够:
  补充额外的Bean
  覆盖已存在的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来排除TestConfig(ExcludeConfig2):
@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);
  }
  }
相关文章:

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
22/2<12
100家互联网大公司java笔试题汇总,填问卷领取~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号