我有一个示例Spring Boot应用程序,其中包含以下内容
引导主类
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
控制器
@RestController
@EnableAutoConfiguration
public class HelloWorld {
@RequestMapping("/")
String gethelloWorld() {
return "Hello World!";
}
}
为控制器编写单元测试的最简单方法是什么?我尝试了以下但它抱怨无法自动装载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() {
}
}
答案 0 :(得分:41)
Spring MVC提供了一个standaloneSetup,它支持测试相对简单的控制器,而无需上下文。
通过注册一个或多个@Controller的实例来构建MockMvc 以编程方式配置Spring MVC基础结构。这允许 完全控制控制器的实例化和初始化, 和它们的依赖关系,类似于普通的单元测试,同时也在制作 可以一次测试一个控制器。
控制器的示例测试可以简单到
public class DemoApplicationTests {
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = 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"));
}
}
答案 1 :(得分:27)
Spring Boot 1.4.M2
中推出的新测试改进可以帮助减少编写这些情况所需的代码量。
测试看起来如此:
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.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"));
}
}
有关详细信息和this
,请参阅documentation博客文章答案 2 :(得分:5)
这是使用Spring MVC的standaloneSetup的另一个答案。使用这种方式,您可以自动装配控制器类或模拟它。
import static org.mockito.Mockito.mock;
import static org.springframework.test.web.server.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.server.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.server.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.web.server.MockMvc;
import org.springframework.test.web.server.setup.MockMvcBuilders;
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class DemoApplicationTests {
final String BASE_URL = "http://localhost:8080/";
@Autowired
private HelloWorld controllerToTest;
private MockMvc mockMvc;
@Before
public void setup() {
this.mockMvc = MockMvcBuilders.standaloneSetup(controllerToTest).build();
}
@Test
public void testSayHelloWorld() throws Exception{
//Mocking Controller
controllerToTest = mock(HelloWorld.class);
this.mockMvc.perform(get("/")
.accept(MediaType.parseMediaType("application/json;charset=UTF-8")))
.andExpect(status().isOk())
.andExpect(content().mimeType(MediaType.APPLICATION_JSON));
}
@Test
public void contextLoads() {
}
}
答案 3 :(得分:4)
将@WebAppConfiguration
(org.springframework.test.context.web.WebAppConfiguration
)注释添加到您的DemoApplicationTests类中将会有效。
答案 4 :(得分:0)
假设我在RestController
操作中使用GET/POST/PUT/DELETE
,并且必须使用spring boot编写单元测试。我将只共享RestController类的代码和相应的单元测试。不会共享任何其他代码与控制器相关的代码,可以对此进行假设。
@RestController
@RequestMapping(value = “/myapi/myApp” , produces = {"application/json"})
public class AppController {
@Autowired
private AppService service;
@GetMapping
public MyAppResponse<AppEntity> get() throws Exception {
MyAppResponse<AppEntity> response = new MyAppResponse<AppEntity>();
service.getApp().stream().forEach(x -> response.addData(x));
return response;
}
@PostMapping
public ResponseEntity<HttpStatus> create(@RequestBody AppRequest request) throws Exception {
//Validation code
service.createApp(request);
return ResponseEntity.ok(HttpStatus.OK);
}
@PutMapping
public ResponseEntity<HttpStatus> update(@RequestBody IDMSRequest request) throws Exception {
//Validation code
service.updateApp(request);
return ResponseEntity.ok(HttpStatus.OK);
}
@DeleteMapping
public ResponseEntity<HttpStatus> delete(@RequestBody AppRequest request) throws Exception {
//Validation
service.deleteApp(request.id);
return ResponseEntity.ok(HttpStatus.OK);
}
}
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = Main.class)
@WebAppConfiguration
public abstract class BaseTest {
protected MockMvc mvc;
@Autowired
WebApplicationContext webApplicationContext;
protected void setUp() {
mvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
protected String mapToJson(Object obj) throws JsonProcessingException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.writeValueAsString(obj);
}
protected <T> T mapFromJson(String json, Class<T> clazz)
throws JsonParseException, JsonMappingException, IOException {
ObjectMapper objectMapper = new ObjectMapper();
return objectMapper.readValue(json, clazz);
}
}
public class AppControllerTest extends BaseTest {
@MockBean
private IIdmsService service;
private static final String URI = "/myapi/myApp";
@Override
@Before
public void setUp() {
super.setUp();
}
@Test
public void testGet() throws Exception {
AppEntity entity = new AppEntity();
List<AppEntity> dataList = new ArrayList<AppEntity>();
AppResponse<AppEntity> dataResponse = new AppResponse<AppEntity>();
entity.setId(1);
entity.setCreated_at("2020-02-21 17:01:38.717863");
entity.setCreated_by(“Abhinav Kr”);
entity.setModified_at("2020-02-24 17:01:38.717863");
entity.setModified_by(“Jyoti”);
dataList.add(entity);
dataResponse.setData(dataList);
Mockito.when(service.getApp()).thenReturn(dataList);
RequestBuilder requestBuilder = MockMvcRequestBuilders.get(URI)
.accept(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
String expectedJson = this.mapToJson(dataResponse);
String outputInJson = mvcResult.getResponse().getContentAsString();
assertEquals(HttpStatus.OK.value(), response.getStatus());
assertEquals(expectedJson, outputInJson);
}
@Test
public void testCreate() throws Exception {
AppRequest request = new AppRequest();
request.createdBy = 1;
request.AppFullName = “My App”;
request.appTimezone = “India”;
String inputInJson = this.mapToJson(request);
Mockito.doNothing().when(service).createApp(Mockito.any(AppRequest.class));
service.createApp(request);
Mockito.verify(service, Mockito.times(1)).createApp(request);
RequestBuilder requestBuilder = MockMvcRequestBuilders.post(URI)
.accept(MediaType.APPLICATION_JSON).content(inputInJson)
.contentType(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
assertEquals(HttpStatus.OK.value(), response.getStatus());
}
@Test
public void testUpdate() throws Exception {
AppRequest request = new AppRequest();
request.id = 1;
request.modifiedBy = 1;
request.AppFullName = “My App”;
request.appTimezone = “Bharat”;
String inputInJson = this.mapToJson(request);
Mockito.doNothing().when(service).updateApp(Mockito.any(AppRequest.class));
service.updateApp(request);
Mockito.verify(service, Mockito.times(1)).updateApp(request);
RequestBuilder requestBuilder = MockMvcRequestBuilders.put(URI)
.accept(MediaType.APPLICATION_JSON).content(inputInJson)
.contentType(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
assertEquals(HttpStatus.OK.value(), response.getStatus());
}
@Test
public void testDelete() throws Exception {
AppRequest request = new AppRequest();
request.id = 1;
String inputInJson = this.mapToJson(request);
Mockito.doNothing().when(service).deleteApp(Mockito.any(Integer.class));
service.deleteApp(request.id);
Mockito.verify(service, Mockito.times(1)).deleteApp(request.id);
RequestBuilder requestBuilder = MockMvcRequestBuilders.delete(URI)
.accept(MediaType.APPLICATION_JSON).content(inputInJson)
.contentType(MediaType.APPLICATION_JSON);
MvcResult mvcResult = mvc.perform(requestBuilder).andReturn();
MockHttpServletResponse response = mvcResult.getResponse();
assertEquals(HttpStatus.OK.value(), response.getStatus());
}
}