【问题标题】:JUnit 5 TestTemplates and Extensions: Accessing TestTemplateInvocationContext?JUnit 5 TestTemplates 和扩展:访问 TestTemplateInvocationContext?
【发布时间】:2017-11-10 13:13:04
【问题描述】:

用例:

  • 应使用不同的参数执行测试。
  • 对于这个测试,我们想使用一个扩展来做一些预处理/后处理。此步骤需要访问当前设置的参数。

最初我尝试使用@ParameterizedTest 来实现它。这里扩展没有机会访问参数(参数在beforeTestExecution 调用之后进行评估)。为此,我使用了@TemplateTestTestTemplateInvocationContextProvider(如guide 中所述)。现在我可以在extensionContext 中看到我的参数。不幸的是,缺少访问器方法:

  • MethodExtensionContext (resp. super class): getTestDescriptor() : TestTemplateInvocationTestDescriptor
  • TestTemplateInvocationTestDescriptor:getInvocationContext()

作为一个有希望的临时解决方法,我进行了一些思考以访问我的invocationContext。 有什么东西反对引入这些访问器方法吗?有没有更好/更简单的方法来做到这一点?

【问题讨论】:

    标签: java junit5


    【解决方案1】:

    我认为您可以在TestTemplateInvocationContext 中提供额外的扩展。以下内容基于用户指南中的示例:

    @TestTemplate
    @ExtendWith(MyTestTemplateInvocationContextProvider.class)
    void testTemplate(String parameter) {
        System.out.println("Test with parameter: " + parameter);
        assertEquals(3, parameter.length());
    }
    
    static class MyTestTemplateInvocationContextProvider implements TestTemplateInvocationContextProvider {
        @Override
        public boolean supportsTestTemplate(ExtensionContext context) {
            return true;
        }
    
        @Override
        public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(ExtensionContext context) {
            return Stream.of(invocationContext("foo"), invocationContext("bar"));
        }
    
        private TestTemplateInvocationContext invocationContext(String parameter) {
            return new TestTemplateInvocationContext() {
                @Override
                public String getDisplayName(int invocationIndex) {
                    return parameter;
                }
    
                @Override
                public List<Extension> getAdditionalExtensions() {
                    return Arrays.asList(parameterResolver(), preProcessor(), postProcessor());
                }
    
                private BeforeTestExecutionCallback preProcessor() {
                    return new BeforeTestExecutionCallback() {
    
                        @Override
                        public void beforeTestExecution(ExtensionContext context) throws Exception {
                            System.out.println("Pre-process parameter: " + parameter);
                        }
                    };
                }
    
                private AfterTestExecutionCallback postProcessor() {
                    return new AfterTestExecutionCallback() {
    
                        @Override
                        public void afterTestExecution(ExtensionContext context) throws Exception {
                            System.out.println("Post-process parameter: " + parameter);
                        }
    
                   };
                }
    
                private ParameterResolver parameterResolver() {
                    return new ParameterResolver() {
                        @Override
                        public boolean supportsParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
                            return parameterContext.getParameter()
                                    .getType()
                                    .equals(String.class);
                        }
    
                        @Override
                        public Object resolveParameter(ParameterContext parameterContext, ExtensionContext extensionContext) {
                            return parameter;
                        }
                    };
                }
            };
        }
    }
    

    控制台输出为:

    Pre-process parameter: foo
    Test with parameter: foo
    Post-process parameter: foo
    Pre-process parameter: bar
    Test with parameter: bar
    Post-process parameter: bar
    

    【讨论】:

      【解决方案2】:

      这意味着我必须将一个扩展名扩展到另一个。目前我有两个扩展:一个(MyProvider)实现TestTemplateInvocationContextProvider(用于测试参数化)和一个(MyCallback)实现BeforeTestExecutionCallback,用于做一些准备工作。

      这看起来像:

        @ExtendWith(MyCallback.class)
        public class WebTest {
          @TestTemplate
          @ExtendWith(MyProvider.class)
          public void showPage() throws Exception {
          }
        }
      

      我的目标是在类级别扩展中获取当前参数:

        public class MyCallback implements BeforeAllCallback, BeforeTestExecutionCallback {
        public void beforeAll(ExtensionContext ctx) {
        }
        public void beforeTestExecution(ExtensionContext ctx) {
          // HERE I WANT CURRENT PARAMETER VALUE:
          ((TestTemplateInvocationTestDescriptor) ((MethodExtensionContext) ctx).testDescriptor).invocationContext;
        }
      

      如果我添加了两个公共方法(如第一次编辑中所述),这是可能的,但可能违反了这个概念?

      【讨论】:

      • 我现在拆分 MyCallback 并将 BeforeTestExecutionCallback 部分移动到我添加到 getAdditionalExtensions 的新扩展中(按照建议)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-06-08
      • 2023-03-12
      • 2019-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多