pba*_*ski 214 java spring mocking spring-test-mvc
我有简单的集成测试
@Test
public void shouldReturnErrorMessageToAdminWhenCreatingUserWithUsedUserName() throws Exception {
mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
.content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
.andDo(print())
.andExpect(status().isBadRequest())
.andExpect(?);
}
Run Code Online (Sandbox Code Playgroud)
在最后一行中,我想将响应体中收到的字符串与期望的字符串进行比较
作为回应,我得到:
MockHttpServletResponse:
Status = 400
Error message = null
Headers = {Content-Type=[application/json]}
Content type = application/json
Body = "Username already taken"
Forwarded URL = null
Redirected URL = null
Run Code Online (Sandbox Code Playgroud)
尝试使用content(),body()但没有任何效果.
Sot*_*lis 316
您可以调用andReturn()
并使用返回的MvcResult
对象来获取内容String
.见下文:
MvcResult result = mockMvc.perform(post("/api/users").header("Authorization", base64ForTestUser).contentType(MediaType.APPLICATION_JSON)
.content("{\"userName\":\"testUserDetails\",\"firstName\":\"xxx\",\"lastName\":\"xxx\",\"password\":\"xxx\"}"))
.andDo(MockMvcResultHandlers.print())
.andExpect(status().isBadRequest())
.andReturn();
String content = result.getResponse().getContentAsString();
// do what you will
Run Code Online (Sandbox Code Playgroud)
pba*_*ski 92
@Sotirios Delimanolis回答了这项工作,但我正在寻找比较这个mockMvc断言中的字符串
所以这就是
.andExpect(content().string("\"Username already taken - please try with different username\""));
Run Code Online (Sandbox Code Playgroud)
当然我的断言失败了:
java.lang.AssertionError: Response content expected:
<"Username already taken - please try with different username"> but was:<"Something gone wrong">
Run Code Online (Sandbox Code Playgroud)
因为:
MockHttpServletResponse:
Body = "Something gone wrong"
Run Code Online (Sandbox Code Playgroud)
所以这证明它有效!
ver*_*tti 58
Spring MockMvc现在直接支持JSON.所以你只要说:
.andExpect(content().json("{'message':'ok'}"));
Run Code Online (Sandbox Code Playgroud)
与字符串比较不同,它会说"缺少字段xyz"或"消息预期'确定'得到'nok'.
这个方法是在Spring 4.1中引入的.
Jer*_*emy 44
阅读这些答案,我可以看到很多与Spring版本4.x相关的内容,我出于各种原因使用版本3.2.0.所以像json直接支持的东西content()
是不可能的.
我发现使用起来MockMvcResultMatchers.jsonPath
非常简单并且有效.这是测试post方法的示例.
这个解决方案的好处是你仍然匹配属性,而不是依赖于完整的json字符串比较.
(使用org.springframework.test.web.servlet.result.MockMvcResultMatchers
)
String expectedData = "some value";
mockMvc.perform(post("/endPoint")
.contentType(MediaType.APPLICATION_JSON)
.content(mockRequestBodyAsString.getBytes()))
.andExpect(status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$.data").value(expectedData));
Run Code Online (Sandbox Code Playgroud)
请求体只是一个json字符串,如果你愿意的话你可以从一个真正的json模拟数据文件中轻松加载,但是我没有在这里包含它,因为它会偏离问题.
返回的实际json看起来像这样:
{
"data":"some value"
}
Run Code Online (Sandbox Code Playgroud)
Mic*_*l W 23
Spring security @WithMockUser
和hamcrest的containsString
匹配器提供了一个简单而优雅的解决方案:
@Test
@WithMockUser(roles = "USER")
public void loginWithRoleUserThenExpectUserSpecificContent() throws Exception {
mockMvc.perform(get("/index"))
.andExpect(status().isOk())
.andExpect(content().string(containsString("This content is only shown to users.")));
}
Run Code Online (Sandbox Code Playgroud)
use*_*759 23
摘自spring的教程
mockMvc.perform(get("/" + userName + "/bookmarks/"
+ this.bookmarkList.get(0).getId()))
.andExpect(status().isOk())
.andExpect(content().contentType(contentType))
.andExpect(jsonPath("$.id", is(this.bookmarkList.get(0).getId().intValue())))
.andExpect(jsonPath("$.uri", is("http://bookmark.com/1/" + userName)))
.andExpect(jsonPath("$.description", is("A description")));
Run Code Online (Sandbox Code Playgroud)
is
可以从 import static org.hamcrest.Matchers.*;
jsonPath
可以从 import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
和jsonPath
参考可以在这里找到
小智 8
here a more elegant way
mockMvc.perform(post("/retrieve?page=1&countReg=999999")
.header("Authorization", "Bearer " + validToken))
.andExpect(status().isOk())
.andExpect(content().string(containsString("regCount")));
Run Code Online (Sandbox Code Playgroud)
这是一个如何解析 JSON 响应,甚至如何使用 JSON 形式的 bean 发送请求的示例:
@Autowired
protected MockMvc mvc;
private static final ObjectMapper MAPPER = new ObjectMapper()
.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false)
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.registerModule(new JavaTimeModule());
public static String requestBody(Object request) {
try {
return MAPPER.writeValueAsString(request);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
public static <T> T parseResponse(MvcResult result, Class<T> responseClass) {
try {
String contentAsString = result.getResponse().getContentAsString();
return MAPPER.readValue(contentAsString, responseClass);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void testUpdate() {
Book book = new Book();
book.setTitle("1984");
book.setAuthor("Orwell");
MvcResult requestResult = mvc.perform(post("http://example.com/book/")
.contentType(MediaType.APPLICATION_JSON)
.content(requestBody(book)))
.andExpect(status().isOk())
.andReturn();
UpdateBookResponse updateBookResponse = parseResponse(requestResult, UpdateBookResponse.class);
assertEquals("1984", updateBookResponse.getTitle());
assertEquals("Orwell", updateBookResponse.getAuthor());
}
Run Code Online (Sandbox Code Playgroud)
正如您在这里看到的,这Book
是一个请求 DTO,UpdateBookResponse
是一个从 JSON 解析的响应对象。您可能想要更改 Jackson 的ObjectMapper
配置。
一种可能的方法是简单地包含gson
依赖项:
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
</dependency>
Run Code Online (Sandbox Code Playgroud)
并解析值以进行验证:
@RunWith(SpringRunner.class)
@WebMvcTest(HelloController.class)
public class HelloControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private HelloService helloService;
@Before
public void before() {
Mockito.when(helloService.message()).thenReturn("hello world!");
}
@Test
public void testMessage() throws Exception {
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders.get("/"))
.andExpect(status().isOk())
.andExpect(content().contentTypeCompatibleWith(MediaType.APPLICATION_JSON_VALUE))
.andReturn();
String responseBody = mvcResult.getResponse().getContentAsString();
ResponseDto responseDto
= new Gson().fromJson(responseBody, ResponseDto.class);
Assertions.assertThat(responseDto.message).isEqualTo("hello world!");
}
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是:
when:
def response = mockMvc.perform(
get('/path/to/api')
.header("Content-Type", "application/json"))
then:
response.andExpect(status().isOk())
response.andReturn().getResponse().getContentAsString() == "what you expect"
Run Code Online (Sandbox Code Playgroud)