spring boot test unable to inject TestRestTemplate and MockMvc

I am using spring boot 1.4.0.RELEASE. I am writing tests for my controller class. I get the following exception.

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.concur.cognos.authentication.service.ServiceControllerITTest': Unsatisfied dependency expressed through field 'restTemplate': No qualifying bean of type [org.springframework.boot.test.web.client.TestRestTemplate] found for dependency [org.springframework.boot.test.web.client.TestRestTemplate]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [org.springframework.boot.test.web.client.TestRestTemplate] found for dependency [org.springframework.boot.test.web.client.TestRestTemplate]: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

Here is my test class

public class ServiceControllerITTest extends ApplicationTests {

    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private MockMvc mvc;

    @Test
    public void exampleTest() throws Exception {
         // test
    }
}

ApplicationTests.java

@RunWith(SpringRunner.class)
@SpringBootTest
@WebAppConfiguration
//@DirtiesContext
public class ApplicationTests {

    @Autowired
    Environment env;

    @Test
    public void contextLoads() {

    }

}

TestRestTemplate is only auto-configured when @SpringBootTest has been configured with a webEnvironment that means it starts the web container and listens for HTTP requests. For example:

@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)

If you read the java doc of SpringBootTest annotation, it says that annotation provides below features (not listing all of them here, but only what are relevant to the question.)

  • Provides support for different webEnvironment modes, including the ability to start a fully running web server listening on a defined or random port.
  • Registers a TestRestTemplate and/or WebTestClient bean for use in web tests that are using a fully running web server listening on a defined or random port.

So @SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT) provides the ability to autowire TestRestTemplate because it starts a fully running web server [as mentioned in @AndyWilkinson' answer as well].

But if you want to autowire MockMvc as well in same TestClass then use @AutoConfigureMockMvc annotation over TestClass.

This is how a Test class may look like:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment=WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
public class SBTest {
    @Autowired
    private TestRestTemplate restTemplate;

    @Autowired
    private MockMvc mvc;

   // tests
}

To work with that, don't use a deprecated TestRestTemplate.

Deprecated:

import org.springframework.boot.test.TestRestTemplate;

Correct:

import org.springframework.boot.test.web.client.TestRestTemplate;

Then you can use the @Autowired annotation in your class:

@Autowired
private TestRestTemplate restTemplate;

And don't use:

@Autowired
private MockMvc mvc;

Both together doesn't work.


According to Spring boot documentation :

You can also auto-configure MockMvc in a non-@WebMvcTest (e.g. SpringBootTest) by annotating it with @AutoConfigureMockMvc.