Search code examples
javaspringspring-bootunit-testingautomated-tests

Testing Spring Boot Library Modules


I got a multi module project where not every module is actually an application but a lot of them are libs. Those libs are doing the major work and I want to test them where they are implemented. The current dependencies of the libs:

implementation 'org.springframework.boot:spring-boot-starter'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

In the main source is a class with @Configuration and a single bean:

@Bean public String testString() { return "A Test String"; }

I got 2 test classes:

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles({"default", "test"}) 
public class Test1 {  

    @Test
    public void conextLoaded() {
    }
}

-

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles({"default", "test"}) 
public class Test2 {  
    @Autowired
    private String testString; 

    @Test
    public void conextLoaded() {
    }
}

The first test works. The second does not. There is not @SpringBootApplication anywhere in that project so in the same package as the Tests I added a test configuration:

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan("com.to.config") 
public class LibTestConfiguration {
}

And it does not work. Same for classes that are @Service. They are not in the context. How can I make it behave like a normal Spring boot application without it actually beeing one and load the configs and contexts from the configurations files I need? The default and test profile share most of their properties (for now) and I want them to be loaded like I would start a tomcat.


Solution

  • I switched to JUnit 5 and made it kinda work... So if you want to test Database stuff:

    @DataMongoTest
    @ExtendWith(SpringExtension.class)
    @ActiveProfiles({"default", "test"})
    class BasicMongoTest { ... }
    
    • Lets you autowire all repositories and mongo template
    • Initializes with apllicaton.yml config
    • Does NOT initialize or configure interceptors

    Full application context test if you have a class with @SpringBootApplication in your classpath (Can be an empty test main in your test context)

    @SpringBootTest
    @ExtendWith(SpringExtension.class)
    @ActiveProfiles({"default", "test"})
    public class FullContextTest { ... }
    
    • Initializes the full context with all configs and beans
    • Should not be done if not necessary as it loads all the application context and kinda defeats the purpose of unit tests to only activate whats needed.

    Test only specific components and configs:

    @SpringBootTest(classes = {Config1.class, Component1.class})
    @EnableConfigurationProperties
    @ExtendWith(SpringExtension.class)
    @ActiveProfiles({"default", "test"})
    public class SpecificComponentsTest { ... }
    
    • Initializes the context with only the Config1 and Component1 classes. Component1 and all beans in Config1 can be autowired.