学习Spring中, 发现在Junit5下Spring测试case上会添加@ExtendWith(SpringExtension.class) 该注解的掌握与使用对于日常开发中的写单测很有帮助.
@ExtendWith(SpringExtension.class) @ContextConfiguration(classes = { BirdConfig.class, CatConfig.class, DogConfig.class }) class ConfigUnitTest { @Autowired ApplicationContext context; @Test void givenImportedBeans_whenGettingEach_shallFindIt() { assertThatBeanExists("dog", Dog.class); assertThatBeanExists("cat", Cat.class); assertThatBeanExists("bird", Bird.class); } private void assertThatBeanExists(String beanName, Class> beanClass) { assertTrue(context.containsBean(beanName)); assertNotNull(context.getBean(beanClass)); } }
@ExtendWith(SpringExtension.class)提供了Spring单测的上下文环境, 会启动一个用于单测的spring容器, 完成单测中所需的bean对象的构建与自动注入. 而其实现上则利用了则利用了: Junit5提供的@ExtendWith扩展能力 + Spring单测需要的SpringExtension.class
@ExtendWith是Junit5新引入的注解, 用于扩展test能力, 通过提供一系列的扩展点(extension point)来支持用户在执行具体的单测实例前后去做一些环境准备等工作, 这部分工作与单测内容无关, 但对于单测的正常执行却至关重要, 比如Spring单测需要启动一个spring容器, 完成指定bean的构建; 或执行测试数据库前进行连接数据库等工作.
如果将每个单测实例比成一个关注点(joint point), 则该思想类似于AOP, 通过@ExtendWith导入指定的Extention类所定义的功能扩展点,
对于单测实例来说常见的扩展点主要包含:
通过实现并注册这些扩展点所定义的接口到Junit5中, 完成更复杂场景单测实例的构建.
SpringExtension是对上述功能扩展点的一种实现, 用来将Spring Test Framework 集成到Junit5测试环境中, 其类定义实现了生命周期回调/测试实例后处理/参数解析等扩展点的接口, 具体类定义如下:
public class SpringExtension implements BeforeAllCallback, AfterAllCallback, TestInstancePostProcessor, BeforeEachCallback, AfterEachCallback, BeforeTestExecutionCallback, AfterTestExecutionCallback, ParameterResolver { ... }
通过这些扩展点, 完成Spring的TestContext构建与初始化, 并将指定的类的bean的构建.
@Configuration