简体   繁体   中英

How to run the same SpringBootTests for different applications

I have a SpringBoot multimodule application, something like that:

core customer1 -> depends on core customer2 -> depends on core

I want to write integration tests for both, but I don't want to duplicate my core test code. Now I have an abstract class with SpringBootTest(classes = Customer1Application.class) and a lot of test classes, mostly testing the core functionality.

@ContextConfiguration
@SpringBootTest(classes = Customer1Application.class)
@AutoConfigureMockMvc
public abstract class AbstractSpringBootTest
{

@Autowired
protected MockMvc                               mockMvc;

@Autowired
protected Validator                             validator;

...
}

I want to check if the changes in Customer2 application break something in core functionality, so I want to run these tests with @SpringBootTest(classes = Customer2Application.class) annotation.

How is it possible to configure the application class in the annotation? Is there a way to run the tests with my other application context without manually changing the annotation or duplicating all the steps?

I don't know if it will work, but I would try removing @SpringBootTest from AbstractSpringBootTest and then defining two test classes as follows:

@SpringBootTest(classes = Customer1Application.class)
class Customer1ApplicationSpringBootTest extends AbstractSpringBootTest {}

@SpringBootTest(classes = Customer2Application.class)
class Customer2ApplicationSpringBootTest extends AbstractSpringBootTest {}

EDIT:

So I dug around Spring Boot sources and came up with this solution .

Essentially to be able to use system property or property file to configure which @SpringBootApplication is supposed to be tested you need to copy the source of class org.springframework.boot.test.context.SpringBootConfigurationFinder to your own test source root and the edit method private Class<?> scanPackage(String source) to look something like this (you do not have to use Lombok of course):

private Class<?> scanPackage(String source) {
    while (!source.isEmpty()) {
        val components = this.scanner.findCandidateComponents(source);
        val testConfig = System.getProperties();
        val testConfigFile = "test-config.properties";
        val applicationClassConfigKey = "main.application.class";
        try {
            testConfig.load(this.getClass().getResourceAsStream("/" + testConfigFile));
        } catch (IOException e) {
            logger.error("Error reading configuration file: {}, using default algorithm", testConfigFile);
        }
        if (testConfig.containsKey(applicationClassConfigKey)) {
            if (!components.isEmpty() && testConfig.containsKey(applicationClassConfigKey) && testConfig.getProperty(applicationClassConfigKey) != null) {
                boolean found = false;
                val configClassName = testConfig.getProperty(applicationClassConfigKey);
                for (BeanDefinition component: components) {
                    if (configClassName.equals(component.getBeanClassName())) {
                        found = true;
                        break;
                    }
                }
                Assert.state(found,
                    () -> "Found multiple @SpringBootConfiguration annotated classes "
                        + components + ", none of which are of type " + configClassName);
                return ClassUtils.resolveClassName(
                    configClassName, null);
            }
        } else {
            if (!components.isEmpty()) {
                Assert.state(components.size() == 1,
                    () -> "Found multiple @SpringBootConfiguration annotated classes "
                                    + components);
                return ClassUtils.resolveClassName(
                     components.iterator().next().getBeanClassName(), null);
            }
        }
        source = getParentPackage(source);
    }
    return null;
}

Check the link for the entire project.

Did you check? @SpringBootTest(classes = {Customer1Application.class, Customer2Application.class})

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM