代码之家  ›  专栏  ›  技术社区  ›  gkatzioura

JUNIT 5:将spring组件注入自定义TestTemplateInvocationContextProvider

  •  4
  • gkatzioura  · 技术社区  · 6 年前

    JUnit Jupiter(JUnit 5)中有没有一种方法可以将Spring组件注入到 TestTemplateInvocationContextProvider ?

    1 回复  |  直到 6 年前
        1
  •  7
  •   Sam Brannen    6 年前

    是的,如果您注册 TestTemplateInvocationContextProvider 就像春天的豆子 ApplicationContext 为您的测试类加载,然后您可以让提供程序 @Autowired 并使用注册为JUnit Jupiter扩展 @RegisterExtension 。诀窍是,您需要使用每类测试实例生命周期模式,以便尽早注册提供程序,以便JUnit Jupiter使用它。

    以下是的修改版本 TestTemplateDemo 来自JUnit 5用户指南。

    测试“按原样”通过,但您可以删除 // @Bean 声明 baz bean来查看测试失败。

    @SpringJUnitConfig
    @TestInstance(Lifecycle.PER_CLASS)
    class TestTemplateDemo {
    
        @Autowired
        @RegisterExtension
        TestTemplateInvocationContextProvider testTemplateInvocationContextProvider;
    
        @TestTemplate
        void testTemplate(String parameter) {
            assertTrue("foo".equals(parameter) || "bar".equals(parameter));
        }
    
        @Configuration
        static class Config {
    
            @Bean
            String foo() {
                return "foo";
            }
    
            @Bean
            String bar() {
                return "bar";
            }
    
            // @Bean
            String baz() {
                return "baz";
            }
    
            @Bean
            TestTemplateInvocationContextProvider myTestTemplateInvocationContextProvider(
                    List<String> parameters) {
    
                return new MyTestTemplateInvocationContextProvider(parameters);
            }
        }
    
        public static class MyTestTemplateInvocationContextProvider
                implements TestTemplateInvocationContextProvider {
    
            private final List<String> parameters;
    
            public MyTestTemplateInvocationContextProvider(List<String> parameters) {
                this.parameters = parameters;
            }
    
            @Override
            public boolean supportsTestTemplate(ExtensionContext context) {
                return true;
            }
    
            @Override
            public Stream<TestTemplateInvocationContext> provideTestTemplateInvocationContexts(
                    ExtensionContext context) {
    
                return this.parameters.stream().map(p -> invocationContext(p));
            }
    
            private TestTemplateInvocationContext invocationContext(String parameter) {
                return new TestTemplateInvocationContext() {
    
                    @Override
                    public String getDisplayName(int invocationIndex) {
                        return parameter;
                    }
    
                    @Override
                    public List<Extension> getAdditionalExtensions() {
                        return Collections.singletonList(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;
                            }
                        });
                    }
                };
            }
        }
    
    }