单元测试工具包(Test)
YMP 框架的单元测试工具包,集成了 JUnit 5 和 JUnit 4 的测试开发支持,分别提供了对应的单测、套件扩展类及专属注解与使用方式,封装了核心工具类 YMPTestUtils 统一管理应用初始化逻辑,同时给出了两类 JUnit 版本下模拟控制器请求、存储器接口调用和组合单元测试的具体使用示例,整体支持依赖注入、测试生命周期管理、Bean 工厂注册等功能。
Maven包依赖
<dependency>
<groupId>net.ymate.platform</groupId>
<artifactId>ymate-platform-test</artifactId>
<version>2.1.4</version>
</dependency>
功能说明
JUnit 5 支持
YMPJUnit5Extension
功能特点:
- 实现了
TestInstanceFactory接口,支持通过 YMP 容器创建测试实例 - 实现了
ParameterResolver接口,支持在测试方法中注入IApplication参数 - 实现了
AfterAllCallback接口,支持测试完成后清理缓存和销毁应用 - 使用
WeakReference管理应用缓存,避免内存泄漏 - 自动注册测试类到 YMP 的 Bean 工厂,支持依赖注入
- 完善的应用生命周期管理,测试执行完毕后自动销毁应用
使用方法:
- 通过
@ExtendWith(YMPJUnit5Extension.class)注解启用 - 支持标准的 JUnit 5 生命周期注解(
@BeforeAll、@AfterAll、@BeforeEach、@AfterEach) - 支持
@Inject注解进行依赖注入
测试参数解析:
@ExtendWith(YMPJUnit5Extension.class)
@EnableAutoScan
public class ExampleTest {
@Test
public void testWithApplication(IApplication application) {
// 直接使用注入的 IApplication 实例
Assertions.assertNotNull(application);
}
}
说明:
ParameterResolver仅解析IApplication(含其实现类/子类型,如YMP)类型的参数,其它类型的测试方法参数会抛ParameterResolutionException;普通 Bean 请使用@Inject字段注入。
依赖注入注意事项:
@Inject的目标 Bean 必须是独立的类文件。扫描器会显式过滤类名含$的内部类(XxxTest$DemoUserService),因此写成测试类内部类的@Bean不会被注册,注入结果为null。- 扫描范围:
@EnableAutoScan未指定value时,扫描根 包取「主类所在包」并递归包含子包;测试场景由YMPTestUtils将系统属性ymp.mainClass设为测试类本身,所以默认扫描范围即为测试类所在包及其子包。Bean 放在其它包时,可用@EnableAutoScan(value = {"com.example.service"})显式扩大范围。 - 若确实需要非同包类或特殊类作为 Bean,可通过
YMPTestUtils.InitConfig#setTestClasses或直接调用beanFactory.registerBean(...)显式注册。 getBean(Class)对未注册的类返回null,断言时务必先用Assertions.assertNotNull(...),避免null == null造成的假通过。- 测试类会以单例形式注册到 Bean 工厂(
BeanMeta.create(clazz, true)),JUnit 默认PER_METHOD生命周期下各测试方法共用同一个测试实例,请勿在测试类中放置可变状态字段。
YMPJUnit5Suite
功能特点:
- 基于 JUnit 5 的
@Suite注解,支持组合多个测试类 - 使用独立的
YMPJUnit5SuiteExtension扩展,确保 YMP 应用仅初始化一次 - 支持批量注册多个测试类到 YMP 的 Bean 工厂
- 提供线程安全的初始化机制
- 完善的应用生命周期管理,整个测试套件执行完毕后自动销毁应用
使用方法:
- 通过
@YMPJUnit5Suite({TestClass1.class, TestClass2.class})注解指定测试类 - 支持标准的 YMP 配置注解(
@EnableAutoScan、@EnableBeanProxy