diff --git a/spring-modulith-test/src/main/java/org/springframework/modulith/test/EnableScenarios.java b/spring-modulith-test/src/main/java/org/springframework/modulith/test/EnableScenarios.java new file mode 100644 index 00000000..f71ae7de --- /dev/null +++ b/spring-modulith-test/src/main/java/org/springframework/modulith/test/EnableScenarios.java @@ -0,0 +1,38 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.modulith.test; + +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import java.lang.annotation.Inherited; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +import org.junit.jupiter.api.extension.ExtendWith; + +/** + * Allows using {@link Scenario} as method parameter in integration tests. + * + * @author Oliver Drotbohm + * @see Scenario + */ +@Documented +@Inherited +@Target(value = ElementType.TYPE) +@Retention(RetentionPolicy.RUNTIME) +@ExtendWith(ScenarioParameterResolver.class) +public @interface EnableScenarios {} diff --git a/spring-modulith-test/src/main/java/org/springframework/modulith/test/ScenarioParameterResolver.java b/spring-modulith-test/src/main/java/org/springframework/modulith/test/ScenarioParameterResolver.java index 41909a48..3e6e504f 100644 --- a/spring-modulith-test/src/main/java/org/springframework/modulith/test/ScenarioParameterResolver.java +++ b/spring-modulith-test/src/main/java/org/springframework/modulith/test/ScenarioParameterResolver.java @@ -20,6 +20,8 @@ import org.junit.jupiter.api.extension.ExtensionContext; import org.junit.jupiter.api.extension.ParameterContext; import org.junit.jupiter.api.extension.ParameterResolutionException; import org.junit.jupiter.api.extension.ParameterResolver; +import org.springframework.beans.factory.NoSuchBeanDefinitionException; +import org.springframework.context.ApplicationContext; import org.springframework.test.context.junit.jupiter.SpringExtension; import org.springframework.transaction.support.TransactionTemplate; @@ -30,6 +32,8 @@ import org.springframework.transaction.support.TransactionTemplate; */ class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback { + private static final String MISSING_TRANSACTION_TEMPLATE = "To use a Scenario in an integration test you need to define a bean of type TransactionTemplate! Please check your ApplicationContext setup."; + private final PublishedEventsParameterResolver delegate; /** @@ -70,9 +74,18 @@ class ScenarioParameterResolver implements ParameterResolver, BeforeAllCallback throws ParameterResolutionException { var context = SpringExtension.getApplicationContext(extensionContext); - var operations = context.getBean(TransactionTemplate.class); + var operations = resolveTransactionTemplate(context); var events = (AssertablePublishedEvents) delegate.resolveParameter(parameterContext, extensionContext); return new Scenario(operations, context, events); } + + private TransactionTemplate resolveTransactionTemplate(ApplicationContext context) { + + try { + return context.getBean(TransactionTemplate.class); + } catch (NoSuchBeanDefinitionException o_O) { + throw new ParameterResolutionException(MISSING_TRANSACTION_TEMPLATE, o_O); + } + } } diff --git a/spring-modulith-test/src/test/java/org/springframework/modulith/test/EnableScenarioIntegrationTests.java b/spring-modulith-test/src/test/java/org/springframework/modulith/test/EnableScenarioIntegrationTests.java new file mode 100644 index 00000000..e3a44c75 --- /dev/null +++ b/spring-modulith-test/src/test/java/org/springframework/modulith/test/EnableScenarioIntegrationTests.java @@ -0,0 +1,55 @@ +/* + * Copyright 2023 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.springframework.modulith.test; + +import static org.assertj.core.api.Assertions.*; +import static org.mockito.Mockito.*; + +import example.TestConfiguration; + +import org.junit.jupiter.api.Nested; +import org.junit.jupiter.api.Test; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.modulith.test.EnableScenarioIntegrationTests.TransactionTemplateTestConfiguration; +import org.springframework.transaction.PlatformTransactionManager; +import org.springframework.transaction.support.TransactionTemplate; + +/** + * Integration tests for the usage of {@link EnableScenarios}. + * + * @author Oliver Drotbohm + */ +@Nested +@EnableScenarios +@SpringBootTest(classes = { TestConfiguration.class, TransactionTemplateTestConfiguration.class }) +class EnableScenarioIntegrationTests { + + @Configuration + static class TransactionTemplateTestConfiguration { + + @Bean + TransactionTemplate transactionTemplate() { + return new TransactionTemplate(mock(PlatformTransactionManager.class)); + } + } + + @Test // GH-190 + void injectsScenario(Scenario scenario) { + assertThat(scenario).isNotNull(); + } +}