20

I created multiple spring-boot testing class, (with spring-boot 1.4.0).

FirstActionTest.java:

@RunWith(SpringRunner.class)
@WebMvcTest(FirstAction.class)
@TestPropertySource("classpath:test-application.properties")
public class FirstActionTest {
    @Autowired
    private MockMvc mvc;

    // ...
}

SecondActionTest.java:

@RunWith(SpringRunner.class)
@WebMvcTest(SecondAction.class)
@TestPropertySource("classpath:test-application.properties")
public class SecondActionTest {
    @Autowired
    private MockMvc mvc;

    // ...
}

When run test via:

mvn test

It seems created a spring test context for each testing class, which is not necessary I guess.

The question is:

  • Is it possible to share a single spring test context among multiple testing class, and if yes, how?
3
  • yes it is possible. stackoverflow.com/a/8502023/410677 Commented Oct 25, 2016 at 10:05
  • @kuhajeyan The link is for xml based configuration, even in spring2.5 we can do that quite easily. But with spring-boot, usually there is no configuration file for context, not sure how to adapt that into spring-boot. Commented Oct 25, 2016 at 10:09
  • 1
    Saw on their documentation that it caches the context but not working for me, it reloads for every test class. > Spring’s test framework will cache application contexts between tests. Therefore, as long as your tests share the same configuration (no matter how it’s discovered), the potentially time consuming process of loading the context will only happen once. docs.spring.io/spring-boot/docs/current/reference/html/… Commented Dec 8, 2016 at 11:33

1 Answer 1

16

By using two different classes with @WebMvcTest (i.e @WebMvcTest(FirstAction.class) and @WebMvcTest(SecondAction.class)) you are specifically indicating that you want different application contexts. You can't share a single context in this case because each context contains a different set of beans. If you're controller beans are fairly well behaved then the context should be relatively quick to create and you shouldn't really have a problem.

If you really want to have a context that can be cached and shared across all web tests, then you need to ensure that it contains exactly the same bean definitions. Two options that spring to mind:

1) Use @WebMvcTest without any controller specified.

FirstActionTest:

@RunWith(SpringRunner.class)
@WebMvcTest
@TestPropertySource("classpath:test-application.properties")
public class FirstActionTest {
    @Autowired
    private MockMvc mvc;

    // ...
}

SecondActionTest:

@RunWith(SpringRunner.class)
@WebMvcTest
@TestPropertySource("classpath:test-application.properties")
public class SecondActionTest {
    @Autowired
    private MockMvc mvc;

    // ...
}

2) Don't use @WebMvcTest at all so you get an application context that contains all beans (not just web concerns)

FirstActionTest:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource("classpath:test-application.properties")
public class FirstActionTest {
    @Autowired
    private MockMvc mvc; // use MockMvcBuilders.webAppContextSetup to create mvc

    // ...
}

SecondActionTest:

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource("classpath:test-application.properties")
public class SecondActionTest {
    @Autowired
    private MockMvc mvc; // use MockMvcBuilders.webAppContextSetup to create mvc

    // ...
}

Keep in mind that a cached context can make running multiple tests faster, but if you're repeatedly running a single test at development time, you're paying the cost of creating a lot of beans that then immediately get thrown away.

Sign up to request clarification or add additional context in comments.

11 Comments

For autowiring MockMvc you can also add annotation @AutoConfigureMockMvc when doing @SpringBootTest
Thanks for the clear explanation, I think option 1) would be cool for projects that has multiple spring mvc tests. It would be helpful if these information could be included in spring-boot documents.
When I use @WebMvcTest directly without controller class specified for a test, and start mvn test, it failed to found dependencies autowired, and the error look like this: Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sportsFieldAction': Unsatisfied dependency expressed through field 'dao': No qualifying bean of type [com.sportslight.dao.SportsFieldDao] found for dependency [com.sportslight.dao.SportsFieldDao], thus it seems context failed to find beans, don't know why.
@Ahmed Did you succeed with the solution 1) in the answer ? I got error ... as described in above comment.
Just 2 more things to try before you give up, you should be using spring boot 1.4.2, define all the @MockBean in a base class, so all classes should have same @MockBean even if they dont need it.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.