如何为自定义 ParameterResolver 实现创建测试?
How to create a test for a custom ParameterResolver implementation?
我创建了一个 ParameterResolver 实现,以便将参数注入我的测试方法。
我有一个场景,如果没有相应注释定义的一些适当参数,参数对象的实例化可能会失败并抛出异常。
@TestScenario(homeDirName = "")
@Test
void ensureFailingWithoutProperHomeDirectory(LauncherRuntime launcher) {
assertThrows(MissingPropertiesException.class,
() -> launcher.run());
}
但是这个测试甚至在开始 运行 之前就失败了,并出现 ParameterResolutionException。
我想知道如何测试它。
由于您要测试 ParameterResolver 实现而不是 JUnit 引擎,因此单元测试的入口点应该是实现的 provideArguments
方法。 JUnit 捕获此方法抛出的每个异常并将其添加为新的 ParameterResolutionException 的原因。有两种可能的方法:
A)
如果您的实现应该调用 ExtensionContext
的多个方法,那么将这些方法与您的注释一起模拟。并调用您的实现的 provideArguments
。
B)
如果您的实现应仅使用 ExtensionContext
来获取注释并且不做任何值得测试的事情,那么将主要功能移动到自己的方法中(例如 accept(MyAnnotation)
)并测试此方法。例如,请参阅 here JUnit 开发人员如何将其用于 CVSSource 注释。
这是我的 ResourceFilesArgumentsProvider
/ ResourceFilesSource
注释的示例测试用例:
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class ResourceFilesArgumentsProviderTest {
@Test
public void nonExistingDirectory() throws Exception {
ResourceFilesSource annotation = resourceFiles("/non-existing-dir");
AnnotatedElement annotatedElement = mock(AnnotatedElement.class);
when(annotatedElement.getAnnotation(ResourceFilesSource.class))
.thenReturn(annotation);
ExtensionContext context = mock(ExtensionContext.class);
when(context.getElement()).thenReturn(Optional.of(annotatedElement));
when(context.getTestClass()).thenReturn(Optional.of(getClass()));
assertThrows(NoSuchFileException.class, () -> provideArguments(context));
}
private Stream<Object[]> provideArguments(ExtensionContext context) throws Exception {
ResourceFilesArgumentsProvider provider = new ResourceFilesArgumentsProvider();
return provider.provideArguments(context).map(Arguments::get);
}
private ResourceFilesSource resourceFiles(String directory) {
/* mock the annotation with Mockito, or alternatively create
* an anonymous class with new ResourceFileSource() { ... }
*/
ResourceFilesSource annotation = mock(ResourceFilesSource.class);
when(annotation.directory()).thenReturn(directory);
return annotation;
}
}
我创建了一个 ParameterResolver 实现,以便将参数注入我的测试方法。 我有一个场景,如果没有相应注释定义的一些适当参数,参数对象的实例化可能会失败并抛出异常。
@TestScenario(homeDirName = "")
@Test
void ensureFailingWithoutProperHomeDirectory(LauncherRuntime launcher) {
assertThrows(MissingPropertiesException.class,
() -> launcher.run());
}
但是这个测试甚至在开始 运行 之前就失败了,并出现 ParameterResolutionException。
我想知道如何测试它。
由于您要测试 ParameterResolver 实现而不是 JUnit 引擎,因此单元测试的入口点应该是实现的 provideArguments
方法。 JUnit 捕获此方法抛出的每个异常并将其添加为新的 ParameterResolutionException 的原因。有两种可能的方法:
A)
如果您的实现应该调用 ExtensionContext
的多个方法,那么将这些方法与您的注释一起模拟。并调用您的实现的 provideArguments
。
B)
如果您的实现应仅使用 ExtensionContext
来获取注释并且不做任何值得测试的事情,那么将主要功能移动到自己的方法中(例如 accept(MyAnnotation)
)并测试此方法。例如,请参阅 here JUnit 开发人员如何将其用于 CVSSource 注释。
这是我的 ResourceFilesArgumentsProvider
/ ResourceFilesSource
注释的示例测试用例:
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
class ResourceFilesArgumentsProviderTest {
@Test
public void nonExistingDirectory() throws Exception {
ResourceFilesSource annotation = resourceFiles("/non-existing-dir");
AnnotatedElement annotatedElement = mock(AnnotatedElement.class);
when(annotatedElement.getAnnotation(ResourceFilesSource.class))
.thenReturn(annotation);
ExtensionContext context = mock(ExtensionContext.class);
when(context.getElement()).thenReturn(Optional.of(annotatedElement));
when(context.getTestClass()).thenReturn(Optional.of(getClass()));
assertThrows(NoSuchFileException.class, () -> provideArguments(context));
}
private Stream<Object[]> provideArguments(ExtensionContext context) throws Exception {
ResourceFilesArgumentsProvider provider = new ResourceFilesArgumentsProvider();
return provider.provideArguments(context).map(Arguments::get);
}
private ResourceFilesSource resourceFiles(String directory) {
/* mock the annotation with Mockito, or alternatively create
* an anonymous class with new ResourceFileSource() { ... }
*/
ResourceFilesSource annotation = mock(ResourceFilesSource.class);
when(annotation.directory()).thenReturn(directory);
return annotation;
}
}