JUNIT 5: Inject spring components to custom TestTemplateInvocationContextProvider

非 Y 不嫁゛ 提交于 2019-11-28 09:59:25

问题


Is there a way in JUnit Jupiter (JUnit 5) that makes it possible to inject Spring components into a TestTemplateInvocationContextProvider?


回答1:


Yes, if you register your TestTemplateInvocationContextProvider as a bean in the Spring ApplicationContext loaded for your test class, you can then have the provider @Autowired into a field and registered as a JUnit Jupiter extension using @RegisterExtension. The trick is that you'll need to use the per-class test instance lifecycle mode in order for the provider to be registered early enough for JUnit Jupiter to use it.

The following is a modified version of TestTemplateDemo from the JUnit 5 User Guide.

The tests pass "as is", but you can remove the // from the @Bean declaration for the baz bean to see a test fail.

@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;
                        }
                    });
                }
            };
        }
    }

}


来源:https://stackoverflow.com/questions/50237046/junit-5-inject-spring-components-to-custom-testtemplateinvocationcontextprovide

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!