usr*_*ΛΩΝ 4 spring spring-test spring-annotations
我熟悉复合注释。然而,即使经过一些研究,它们似乎还不足以满足我的特定需求。
我想创建一个用于测试的注释,将其与一些属性放在一个类上,可以自定义测试上下文。
public @interface MyTestingAnnotation {
String myTestingAttribute()
}
Run Code Online (Sandbox Code Playgroud)
的值应该由我的自定义 (TBD )myTestingAttribute之一读取@TestConfiguration
在我的应用程序中,我必须模拟时钟,以便测试可以模拟特定时间点运行。例如,测试结果不依赖于硬件时钟。我java.time.Clock为此目的定义了一个 bean。
目前,我只有一个注释来启用模拟时钟,但指定其时间取决于@TestPropertySource
public @interface MyTestingAnnotation {
String myTestingAttribute()
}
Run Code Online (Sandbox Code Playgroud)
相反,我想注释一个测试@MockClock(at = "2024-02-15T12:35:00+04:00"),而不一定使用属性源语法。
我知道如何@AliasFor在自定义注释中使用,但目前我只能@Import(MockClockConfiguration.class)在元注释中使用。
我怎样才能在 Spring 中实现这样的目标?
您可以使用 aContextCustomizer来达到此目的。
这种方法允许您在运行测试之前修改应用程序上下文,从而提供对上下文配置的细粒度控制,包括添加或覆盖 bean、属性等。
要通过 实现您的目标ContextCustomizer,请按照下列步骤操作:
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MockClock {
String at();
}
Run Code Online (Sandbox Code Playgroud)
ContextCustomizer创建ContextCustomizer将根据@MockClock注释修改应用程序上下文的环境或 bean 定义。
import org.springframework.boot.test.util.TestPropertyValues;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.MergedContextConfiguration;
import java.time.OffsetDateTime;
public class MockClockContextCustomizer implements ContextCustomizer {
private final OffsetDateTime mockTime;
public MockClockContextCustomizer(OffsetDateTime mockTime) {
this.mockTime = mockTime;
}
@Override
public void customizeContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) {
TestPropertyValues.of(
"clock.fixed-instant=" + mockTime.toString())
.applyTo(context);
}
// MockClockContextCustomizer must implement equals() and hashCode(). See the Javadoc for ContextCustomizer for details.
}
Run Code Online (Sandbox Code Playgroud)
ContextCustomizerFactory创建一个在测试类上ContextCustomizerFactory查找注释并根据注释的属性生成一个注释的注释。@MockClockContextCustomizer
import org.springframework.test.context.ContextConfigurationAttributes;
import org.springframework.test.context.ContextCustomizer;
import org.springframework.test.context.ContextCustomizerFactory;
import java.time.OffsetDateTime;
import java.util.List;
public class MockClockContextCustomizerFactory implements ContextCustomizerFactory {
@Override
public ContextCustomizer createContextCustomizer(Class<?> testClass, List<ContextConfigurationAttributes> configAttributes) {
MockClock mockClock = testClass.getAnnotation(MockClock.class);
if (mockClock != null) {
return new MockClockContextCustomizer(OffsetDateTime.parse(mockClock.at()));
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
ContextCustomizerFactorySpring 不会自动发现 ContextCustomizerFactory 实现。要注册自定义工厂,您需要META-INF/spring.factories在项目的资源目录中创建一个名为的文件(如果该文件尚不存在)并添加以下行:
去
org.springframework.test.context.ContextCustomizerFactory=\
your.package.MockClockContextCustomizerFactory
Run Code Online (Sandbox Code Playgroud)
替换your.package为您所在的实际包名称MockClockContextCustomizerFactory。
作为替代方案,您可以从 Spring Framework 6.1 开始ContextCustomizerFactory在本地注册 via @ContextCustomizerFactories。
怎么运行的
@MockClock当执行带有注释的测试类时,Spring Test 会查找ContextCustomizerFactory中指定的实现spring.factories。MockClockContextCustomizerFactory检查注释是否存在,如果找到,则创建具有指定固定时刻@MockClock的实例。MockClockContextCustomizerMockClockContextCustomizer在测试运行之前自定义应用程序上下文,将所需的属性添加到环境中,您MockClockConfiguration可以使用它来创建模拟的 Clock bean。| 归档时间: |
|
| 查看次数: |
377 次 |
| 最近记录: |