raiki_dev’s blog

右も左も分かりませんが、よろしくお願いいたします。

JUnit5で引数の名前と値を取得する方法

JUnit5でテストメソッドの引数の変数名と値を取得したい場合があり、公式GithubのIssueのコメントで流れているとこを発見したので記載しておく。

下記は@BeforeEachを実施する際にフックするメソッド内で該当情報を取得している例だ。 サンプルとして変数名と、変数の値をSysoutするようにしたので編集すれば好きなように使うことができる。 なお、普通に実行しても引数名はargNとなるが、-parametersとJVMOptionを追記することで引数名が取れるようになる。

私の場合、引数名と値と、別途テストクラスの階層やテストクラスを取得することで、実行したときのエビデンス出力するフォルダ構成を作成するために利用した。

class TestExtension
        implements BeforeEachCallback
{
    @Override
    public void beforeEach(ExtensionContext extensionContext)
    {
        Parameter[] parameters = extensionContext.getTestMethod().get().getParameters();
        Object[] argObjects = getArgumentValues(extensionContext);
        for (int i = 0; i < parameters.length; i++)
        {
            // ここで引数名と値を出力している
            System.out.println(parameters[i].getName() + " : " + argObjects[i]);
        }
    }

    private Object[] getArgumentValues(ExtensionContext extensionContext)
    {
        try
        {
            Method method = ReflectionUtils.findMethod(extensionContext.getClass(), "getTestDescriptor").orElse(null);
            TestMethodTestDescriptor descriptor =
                    (TestMethodTestDescriptor)ReflectionUtils.invokeMethod(method, extensionContext);

            //Get the TestTemplateInvocationContext
            Field templateField = descriptor.getClass().getDeclaredField("invocationContext");
            templateField.setAccessible(true);
            TestTemplateInvocationContext template = (TestTemplateInvocationContext)templateField.get(descriptor);

            //Get the params finally
            Field argumentsField = template.getClass().getDeclaredField("arguments");
            argumentsField.setAccessible(true);
            Object[] params = (Object[])argumentsField.get(template);

            return params;

        }
        catch (Exception e)
        {
            return new Object[0];
        }
    }
}

参考

この記事は過去にZennに投稿したものの転載。 zenn.dev