GH-466 - Polishing.
Moved integration test to integration tests module.
This commit is contained in:
@@ -15,23 +15,29 @@
|
||||
*/
|
||||
package otherpackage.integration;
|
||||
|
||||
import example.order.Order;
|
||||
import example.order.OrderManagement;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import static org.assertj.core.api.Assertions.*;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.modulith.test.ApplicationModuleTest;
|
||||
|
||||
import com.acme.myproject.moduleA.ServiceComponentA;
|
||||
|
||||
/**
|
||||
* Test to showcase {@link ApplicationModuleTest} outside of a module package
|
||||
*
|
||||
* @author Lukas Dohmen
|
||||
*/
|
||||
@ApplicationModuleTest(module = "order", classes = {example.Application.class})
|
||||
@RequiredArgsConstructor
|
||||
class OrderIntegrationTests {
|
||||
@ApplicationModuleTest(
|
||||
module = "moduleA",
|
||||
classes = { com.acme.myproject.Application.class },
|
||||
verifyAutomatically = false)
|
||||
class TestOutsideModulePackageIntegrationTests {
|
||||
|
||||
private final OrderManagement orders;
|
||||
@Autowired ServiceComponentA componentA;
|
||||
|
||||
@Test
|
||||
void completesOrder() {
|
||||
orders.complete(new Order());
|
||||
void injectsModuleComponent() {
|
||||
assertThat(componentA).isNotNull();
|
||||
}
|
||||
}
|
||||
@@ -77,10 +77,22 @@ public @interface ApplicationModuleTest {
|
||||
String[] extraIncludes() default {};
|
||||
|
||||
/**
|
||||
* Logical name of the module in case {@link ApplicationModuleTest} will be used outside a module package
|
||||
* Logical name of the module to be bootstrapped in case {@link ApplicationModuleTest} will be used outside a module
|
||||
* package
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
* @since 1.3
|
||||
*/
|
||||
String module() default "";
|
||||
|
||||
/**
|
||||
* Alias for {@link SpringBootTest#classes()}. Useful to define the main application class in case the test is located
|
||||
* outside a module package and that class doesn't reside in any of the parent packages.
|
||||
*
|
||||
* @return will never be {@literal null}.
|
||||
* @see #module()
|
||||
* @since 1.3
|
||||
*/
|
||||
@AliasFor(annotation = SpringBootTest.class)
|
||||
Class<?>[] classes() default {};
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ import java.util.Map;
|
||||
import java.util.Objects;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
@@ -34,11 +35,13 @@ import org.springframework.modulith.core.ApplicationModule;
|
||||
import org.springframework.modulith.core.ApplicationModules;
|
||||
import org.springframework.modulith.core.JavaPackage;
|
||||
import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode;
|
||||
import org.springframework.util.ObjectUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
import org.springframework.util.function.SingletonSupplier;
|
||||
|
||||
/**
|
||||
* @author Oliver Drotbohm
|
||||
* @author Lukas Dohmen
|
||||
*/
|
||||
public class ModuleTestExecution implements Iterable<ApplicationModule> {
|
||||
|
||||
@@ -95,21 +98,14 @@ public class ModuleTestExecution implements Iterable<ApplicationModule> {
|
||||
|
||||
var annotation = AnnotatedElementUtils.findMergedAnnotation(type, ApplicationModuleTest.class);
|
||||
var packageName = type.getPackage().getName();
|
||||
var optionalModulithType = findSpringBootApplicationByClasses(annotation);
|
||||
|
||||
var modulithType = optionalModulithType.orElseGet(() -> MODULITH_TYPES.computeIfAbsent(type,
|
||||
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromPackage(packageName)));
|
||||
var modules = ApplicationModules.of(modulithType);
|
||||
|
||||
var modules = ApplicationModules.of(findSpringBootApplicationByClasses(annotation, type));
|
||||
var moduleName = annotation.module();
|
||||
ApplicationModule module;
|
||||
if (StringUtils.hasText(moduleName)) {
|
||||
module = modules.getModuleByName(moduleName).orElseThrow( //
|
||||
() -> new IllegalStateException(String.format("Unable to find module %s!", moduleName)));
|
||||
} else {
|
||||
module = modules.getModuleForPackage(packageName).orElseThrow( //
|
||||
() -> new IllegalStateException(String.format("Package %s is not part of any module!", packageName)));
|
||||
}
|
||||
|
||||
var module = StringUtils.hasText(moduleName)
|
||||
? modules.getModuleByName(moduleName).orElseThrow( //
|
||||
() -> new IllegalStateException(String.format("Unable to find module %s!", moduleName)))
|
||||
: modules.getModuleForPackage(packageName).orElseThrow( //
|
||||
() -> new IllegalStateException(String.format("Package %s is not part of any module!", packageName)));
|
||||
|
||||
return EXECUTIONS.computeIfAbsent(new Key(module.getBasePackage().getName(), annotation),
|
||||
it -> new ModuleTestExecution(annotation, modules, module));
|
||||
@@ -240,15 +236,22 @@ public class ModuleTestExecution implements Iterable<ApplicationModule> {
|
||||
.flatMap(Optional::stream);
|
||||
}
|
||||
|
||||
private static Optional<Class<?>> findSpringBootApplicationByClasses(ApplicationModuleTest annotation) {
|
||||
for (Class<?> clazz : annotation.classes()) {
|
||||
Class<?> modulithType = MODULITH_TYPES.computeIfAbsent(clazz,
|
||||
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromPackage(clazz.getPackageName()));
|
||||
if (modulithType != null) {
|
||||
return Optional.of(modulithType);
|
||||
}
|
||||
}
|
||||
return Optional.empty();
|
||||
private static Class<?> findSpringBootApplicationByClasses(ApplicationModuleTest annotation,
|
||||
Class<?> testClass) {
|
||||
|
||||
var types = ObjectUtils.addObjectToArray(annotation.classes(), testClass);
|
||||
|
||||
return Arrays.stream(types)
|
||||
.<Class<?>> map(ModuleTestExecution::lookupSpringBootApplicationAnnotation)
|
||||
.findFirst()
|
||||
.orElseThrow(() -> new IllegalStateException("Couldn't find @SpringBootApplication traversing %s."
|
||||
.formatted(Arrays.stream(types).map(Class::getName).collect(Collectors.joining(", ")))));
|
||||
}
|
||||
|
||||
private static Class<?> lookupSpringBootApplicationAnnotation(Class<?> clazz) {
|
||||
|
||||
return MODULITH_TYPES.computeIfAbsent(clazz,
|
||||
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromClass(clazz));
|
||||
}
|
||||
|
||||
private static record Key(String moduleBasePackage, ApplicationModuleTest annotation) {}
|
||||
|
||||
Reference in New Issue
Block a user