簡體   English   中英

是否可以在 Junit 5 中使用 Java 功能接口實現(例如供應商)作為 MethodSource?

[英]Is it possible to use Java functional interface implementation (such as the Supplier) as a MethodSource in Junit 5?

運行集成測試我將它們的參數作為 jsons 存儲在不同的文件中。 這些文件存儲不同的測試用例,然后以不同的方法進行測試。

我想知道是否有可能創建一個通用的讀取文件方法,比如這個:

  static Stream<Arguments> argumentsOf(String fileName) {
    Path argumentsFilePath = Paths.get(ARGUMENTS_FILES_DIRECTORY + fileName);
    //read and return arguments stored in a file 
  }

連同這樣的功能界面:

     static Supplier<Stream<Arguments>> anExampleArgument =
      () -> argumentsOf("some_test_case_argument.json");

所以我可以做這樣的事情:

  @ParameterizedTest
  @MethodSource("anExampleArgument.get")
  void test1(String exampleArgument) {
  //...
  }

我找不到有關此場景的任何信息。 上面看到的示例代碼導致

org.junit.platform.commons.JUnitException: Could not find factory method [anExampleArgument.get] in class [com.company.ExampleIntegrationTest]

不,目前您所描述的似乎不可能。

MethodSource的文檔對此不是很清楚,但查看其 JavaDoc可能會提供一些見解:

外部類中的工廠方法必須由完全限定的方法名稱引用 - 例如, com.example.StringsProviders#blankStrings

拋出您所看到的異常的代碼在這里

private Method getMethod(Class<?> clazz, String methodName) {
    return ReflectionUtils.findMethod(clazz, methodName).orElseThrow(() -> new JUnitException(
    format("Could not find factory method [%s] in class [%s]", methodName, clazz.getName())));
}

可悲的是,他們的ReflectionUtils類似乎不包含任何用於評估方法后附加調用的功能,因此它將您的 String 視為完全限定的方法名稱。

也許您會從按照這個答案創建自己的ArgumentsProvider受益?

正如評論者指出的那樣,也許動態測試也適用於您的用例。

此外,您可以很容易地創建自己的@FileSource注釋:

@Target({ ElementType.ANNOTATION_TYPE, ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ArgumentsSource(FileArgumentsProvider.class)
public @interface FileSource {

    String[] value() default "";

}

ArgumentsProvider一起:

public class FileArgumentsProvider implements ArgumentsProvider, AnnotationConsumer<FileSource> {

    private String[] fileNames;

    @Override
    public void accept(FileSource fileSource) {
        this.fileNames = fileSource.value();
    }

    @Override
    public Stream<? extends Arguments> provideArguments(ExtensionContext context) {
        return Arrays.stream(fileNames).map(this::readFile).map(Arguments::of);
    }

    private String readFile(String fileName) {
        return "the actual content of the file";
    }

}

並像這樣使用它:

@ParameterizedTest
@FileSource({"test_case_1.json", "test_case_2.json", "test_case_3.json"})
void test(String fileContent) {
    // Your test code
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM