Tuesday, July 22, 2014

Spring: Integration testing under Spring Boot application context but mocking services

So I wanted to create some integration tests for an API application that uses Spring Boot. The thing is that I needed to load the same application context as the real applicationm, because Spring Boot performs a bunch of configurations for you, and these were not being loaded in a StandAlone mode.

But also I didn't want to use real services which depend upon real data. Depending on databases for your tests creates fragile tests.

After researching on the web I found this way:


This is the typical Spring-Boot entry point class.

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;

@EnableAutoConfiguration
@ComponentScan
public class MyApplication {

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

A base class having the logic to init the application context.

import static org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup;
import org.junit.Before;
import org.junit.runner.RunWith;
import org.mockito.MockitoAnnotations;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfiguration
@SpringApplicationConfiguration(classes = MyApplication.class)
public abstract class BaseIntegrationTest {

    protected MockMvc mockMvc;
    
    @Autowired
    protected WebApplicationContext wac;

    @Before
    public void setup() {
       
        MockitoAnnotations.initMocks(this);
        this.mockMvc = webAppContextSetup(wac).build();
    }
}

An implementation class mocking a required service class.
public class FooIntegrationTest extends BaseIntegrationTest {

    @Configuration
    public static class TestConfiguration {
        @Bean
        @Primary
        public FooService fooService() {
            return mock(FooService.class);
        }
    }


    @Autowired
    FooService mockFooService;
}

3 comments:

  1. cant get this to work for me. TestConfiguration.fooService is never invoked. Would you have any ideas as to what I might be doing wrong?

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. Hallo Lieber,

    Ich mag deinen Blog sehr viel .. Ich sehe Daily Your Blog, ist ein sehr nützliches für mich.

    bootsprüfung Theorie Schweiz: Alle Informationen zur Schweizer bootsprüfung im effizienten Theorie-Onlinekurs zur Bootsprüfung

    Besuch jetzt -https://www.bootspruefung-schweiz.ch/

    ReplyDelete