Skip to content

Commit 3b85350

Browse files
committed
GH-466 - Polishing.
Moved integration test to integration tests module.
1 parent bf120cf commit 3b85350

File tree

3 files changed

+54
-33
lines changed

3 files changed

+54
-33
lines changed
Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -15,23 +15,29 @@
1515
*/
1616
package otherpackage.integration;
1717

18-
import example.order.Order;
19-
import example.order.OrderManagement;
20-
import lombok.RequiredArgsConstructor;
18+
import static org.assertj.core.api.Assertions.*;
19+
2120
import org.junit.jupiter.api.Test;
21+
import org.springframework.beans.factory.annotation.Autowired;
2222
import org.springframework.modulith.test.ApplicationModuleTest;
2323

24+
import com.acme.myproject.moduleA.ServiceComponentA;
25+
2426
/**
2527
* Test to showcase {@link ApplicationModuleTest} outside of a module package
28+
*
29+
* @author Lukas Dohmen
2630
*/
27-
@ApplicationModuleTest(module = "order", classes = {example.Application.class})
28-
@RequiredArgsConstructor
29-
class OrderIntegrationTests {
31+
@ApplicationModuleTest(
32+
module = "moduleA",
33+
classes = { com.acme.myproject.Application.class },
34+
verifyAutomatically = false)
35+
class TestOutsideModulePackageIntegrationTests {
3036

31-
private final OrderManagement orders;
37+
@Autowired ServiceComponentA componentA;
3238

3339
@Test
34-
void completesOrder() {
35-
orders.complete(new Order());
40+
void injectsModuleComponent() {
41+
assertThat(componentA).isNotNull();
3642
}
3743
}

spring-modulith-test/src/main/java/org/springframework/modulith/test/ApplicationModuleTest.java

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,22 @@
7777
String[] extraIncludes() default {};
7878

7979
/**
80-
* Logical name of the module in case {@link ApplicationModuleTest} will be used outside a module package
80+
* Logical name of the module to be bootstrapped in case {@link ApplicationModuleTest} will be used outside a module
81+
* package
82+
*
83+
* @return will never be {@literal null}.
84+
* @since 1.3
8185
*/
8286
String module() default "";
8387

88+
/**
89+
* Alias for {@link SpringBootTest#classes()}. Useful to define the main application class in case the test is located
90+
* outside a module package and that class doesn't reside in any of the parent packages.
91+
*
92+
* @return will never be {@literal null}.
93+
* @see #module()
94+
* @since 1.3
95+
*/
8496
@AliasFor(annotation = SpringBootTest.class)
8597
Class<?>[] classes() default {};
8698

spring-modulith-test/src/main/java/org/springframework/modulith/test/ModuleTestExecution.java

Lines changed: 26 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
import java.util.Objects;
2424
import java.util.Optional;
2525
import java.util.function.Supplier;
26+
import java.util.stream.Collectors;
2627
import java.util.stream.Stream;
2728

2829
import org.slf4j.Logger;
@@ -34,11 +35,13 @@
3435
import org.springframework.modulith.core.ApplicationModules;
3536
import org.springframework.modulith.core.JavaPackage;
3637
import org.springframework.modulith.test.ApplicationModuleTest.BootstrapMode;
38+
import org.springframework.util.ObjectUtils;
3739
import org.springframework.util.StringUtils;
3840
import org.springframework.util.function.SingletonSupplier;
3941

4042
/**
4143
* @author Oliver Drotbohm
44+
* @author Lukas Dohmen
4245
*/
4346
public class ModuleTestExecution implements Iterable<ApplicationModule> {
4447

@@ -95,21 +98,14 @@ public static Supplier<ModuleTestExecution> of(Class<?> type) {
9598

9699
var annotation = AnnotatedElementUtils.findMergedAnnotation(type, ApplicationModuleTest.class);
97100
var packageName = type.getPackage().getName();
98-
var optionalModulithType = findSpringBootApplicationByClasses(annotation);
99-
100-
var modulithType = optionalModulithType.orElseGet(() -> MODULITH_TYPES.computeIfAbsent(type,
101-
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromPackage(packageName)));
102-
var modules = ApplicationModules.of(modulithType);
103-
101+
var modules = ApplicationModules.of(findSpringBootApplicationByClasses(annotation, type));
104102
var moduleName = annotation.module();
105-
ApplicationModule module;
106-
if (StringUtils.hasText(moduleName)) {
107-
module = modules.getModuleByName(moduleName).orElseThrow( //
108-
() -> new IllegalStateException(String.format("Unable to find module %s!", moduleName)));
109-
} else {
110-
module = modules.getModuleForPackage(packageName).orElseThrow( //
111-
() -> new IllegalStateException(String.format("Package %s is not part of any module!", packageName)));
112-
}
103+
104+
var module = StringUtils.hasText(moduleName)
105+
? modules.getModuleByName(moduleName).orElseThrow( //
106+
() -> new IllegalStateException(String.format("Unable to find module %s!", moduleName)))
107+
: modules.getModuleForPackage(packageName).orElseThrow( //
108+
() -> new IllegalStateException(String.format("Package %s is not part of any module!", packageName)));
113109

114110
return EXECUTIONS.computeIfAbsent(new Key(module.getBasePackage().getName(), annotation),
115111
it -> new ModuleTestExecution(annotation, modules, module));
@@ -240,15 +236,22 @@ private static Stream<ApplicationModule> getExtraModules(ApplicationModuleTest a
240236
.flatMap(Optional::stream);
241237
}
242238

243-
private static Optional<Class<?>> findSpringBootApplicationByClasses(ApplicationModuleTest annotation) {
244-
for (Class<?> clazz : annotation.classes()) {
245-
Class<?> modulithType = MODULITH_TYPES.computeIfAbsent(clazz,
246-
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromPackage(clazz.getPackageName()));
247-
if (modulithType != null) {
248-
return Optional.of(modulithType);
249-
}
250-
}
251-
return Optional.empty();
239+
private static Class<?> findSpringBootApplicationByClasses(ApplicationModuleTest annotation,
240+
Class<?> testClass) {
241+
242+
var types = ObjectUtils.addObjectToArray(annotation.classes(), testClass);
243+
244+
return Arrays.stream(types)
245+
.<Class<?>> map(ModuleTestExecution::lookupSpringBootApplicationAnnotation)
246+
.findFirst()
247+
.orElseThrow(() -> new IllegalStateException("Couldn't find @SpringBootApplication traversing %s."
248+
.formatted(Arrays.stream(types).map(Class::getName).collect(Collectors.joining(", ")))));
249+
}
250+
251+
private static Class<?> lookupSpringBootApplicationAnnotation(Class<?> clazz) {
252+
253+
return MODULITH_TYPES.computeIfAbsent(clazz,
254+
it -> new AnnotatedClassFinder(SpringBootApplication.class).findFromClass(clazz));
252255
}
253256

254257
private static record Key(String moduleBasePackage, ApplicationModuleTest annotation) {}

0 commit comments

Comments
 (0)