Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to write a unit test for a Spring Boot Controller endpoint

I have a sample Spring Boot app with the following

Boot main class

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

Controller

@RestController @EnableAutoConfiguration public class HelloWorld {     @RequestMapping("/")     String gethelloWorld() {         return "Hello World!";     }  } 

What's the easiest way to write a unit test for the controller? I tried the following but it complains about failing to autowire WebApplicationContext

@RunWith(SpringJUnit4ClassRunner.class) @SpringApplicationConfiguration(classes = DemoApplication.class) public class DemoApplicationTests {      final String BASE_URL = "http://localhost:8080/";      @Autowired     private WebApplicationContext wac;      private MockMvc mockMvc;      @Before     public void setup() {         this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();     }      @Test     public void testSayHelloWorld() throws Exception{           this.mockMvc.perform(get("/")                  .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))                  .andExpect(status().isOk())                  .andExpect(content().contentType("application/json"));     }      @Test     public void contextLoads() {     }  } 
like image 446
user6123723 Avatar asked Mar 14 '15 20:03

user6123723


People also ask

How do you write unit test cases for controller in spring boot?

Unit Tests should be written under the src/test/java directory and classpath resources for writing a test should be placed under the src/test/resources directory. For Writing a Unit Test, we need to add the Spring Boot Starter Test dependency in your build configuration file as shown below.

How do you write a unit test for spring boot?

The @Profile(“test”) annotation is used to configure the class when the Test cases are running. Now, you can write a Unit Test case for Order Service under the src/test/resources package. The complete code for build configuration file is given below.


2 Answers

Spring MVC offers a standaloneSetup that supports testing relatively simple controllers, without the need of context.

Build a MockMvc by registering one or more @Controller's instances and configuring Spring MVC infrastructure programmatically. This allows full control over the instantiation and initialization of controllers, and their dependencies, similar to plain unit tests while also making it possible to test one controller at a time.

An example test for your controller can be something as simple as

public class DemoApplicationTests {      private MockMvc mockMvc;      @Before     public void setup() {         this.mockMvc = MockMvcBuilders.standaloneSetup(new HelloWorld()).build();     }      @Test     public void testSayHelloWorld() throws Exception {         this.mockMvc.perform(get("/")            .accept(MediaType.parseMediaType("application/json;charset=UTF-8")))            .andExpect(status().isOk())            .andExpect(content().contentType("application/json"));      } } 
like image 172
Master Slave Avatar answered Sep 24 '22 07:09

Master Slave


The new testing improvements that debuted in Spring Boot 1.4.M2 can help reduce the amount of code you need to write situation such as these.

The test would look like so:

import static org.springframework.test.web.servlet.request.MockMvcRequestB‌​uilders.get;  import static org.springframework.test.web.servlet.result.MockMvcResultMat‌​chers.content;  import static org.springframework.test.web.servlet.result.MockMvcResultMat‌​chers.status;  @RunWith(SpringRunner.class) @WebMvcTest(HelloWorld.class) public class UserVehicleControllerTests {          @Autowired     private MockMvc mockMvc;          @Test     public void testSayHelloWorld() throws Exception {         this.mockMvc.perform(get("/").accept(MediaType.parseMediaType("application/json;charset=UTF-8")))                 .andExpect(status().isOk())                 .andExpect(content().contentType("application/json"));     }      } 

See this blog post for more details as well as the documentation

like image 43
geoand Avatar answered Sep 22 '22 07:09

geoand