简体   繁体   中英

How to test Maven module project with Spring Boot

I have split a project, based on Spring Boot, into several Maven modules. Now only the war-project contains a starter class (having a main method, starting Spring), the other modules are of type jar.

How do I test the jar projects, if they don't include a starter?

Example JUnit test case header:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(StarterClassInDifferentProject.class)
...

I think context tests should be available per module so you can find issues with wire and configuration early on and not depend on your full application tests to find them.

I worked around this issue with a test application class in the same module. Make sure this main class is in your test dir.

@SpringBootApplication
public class TestApplication {
    
    public static void main(String[] args) {
        SpringApplication.run(TestApplication.class, args);
    }
}

your context should work now.

@RunWith(SpringRunner.class)
@ActiveProfiles(profiles = {Profiles.WEB_REST})
@WebMvcTest(EntityController.class)
@DirtiesContext
public class ServicesControllerTest {

    @Autowired
    private MockMvc mvc;

    @MockBean
    private Controller controller;

    @Test
    public void testAll() throws Exception {
        given(controller.process(null)).willReturn(null);

        mvc.perform(get("/").accept(MediaType.APPLICATION_JSON))
                .andExpect(status().isOk());
    }
}

I solved a similar situation. I have a project with two modules:

  1. a "lib" project with domain and utilities classes,
  2. a "web" projects with a spring boot application, templates, controllers, etc...

and I wanted to test the "lib" project in a spring-boot-test fashion.

First, include the required dependencies with scope "test" in the pom.xml (in my case there is also the H2 database):

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>1.3.3.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <!-- add also add this here, even if in my project it is already present as a regular dependency -->
     <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
        <version>1.3.3.RELEASE</version>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <version>1.4.191</version>
        <scope>test</scope>
    </dependency>

For testing purposes, among the test sources of the "lib" project, I have a class that acts as my test configuration

    package my.pack.utils;

    import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
    import org.springframework.boot.autoconfigure.domain.EntityScan;
    import org.springframework.boot.test.context.TestConfiguration;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;

    @TestConfiguration
    @EnableJpaRepositories(basePackages = {"my.pack.engine.storage", "my.pack.storage"})
    @EntityScan(basePackages = {"my.pack.storage", "my.pack.entity"})
    @EnableAutoConfiguration
    public class MyTestConfiguration
    {

    }

This sets up the H2 database in order to test the data access functionalities of the application

Finally, only in the test classes where I find it useful, I configure the execution to use the test configuration (I do not always need to do that, but sometimes it is handy):

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(classes = MyTestConfiguration.class)
    public class TestAClassThatNeedsSpringRepositories
    {
        // tests...
    }

The question is

How do I test the jar projects, if they don't include a starter?

I believe the right answer, is that your jar submodules should not be united tested with spring-boot context.

In fact, most if not all tests in your jar projects should not even use the RunWith(Spring...) They should be vanilla or using a mock library such as @RunWith(MockitoJUnitRunner.class).

If you read SpringApplicationConfiguration's javadoc :

Class-level annotation that is used to determine how to load and configure an ApplicationContext for integration tests .

It is considered integration testing.

Other than that, you can also launch your tests using spring context (not spring-boot) with a 'test spring configuration' in your jar submodule. Define your beans/resources and use it in your test.

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(TestConfigInJarModule.class)

For instance, I do this to test Spring data Repositories, using a test spring configuration (without dependencies on spring-boot).

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