我正在为一个控制器编写测试,该控制器抛出一个自定义异常(在我的例子中是AuthentiationException
),该异常用@响应状态(value=Httpstatus.BAD_REQUEST)
注释
使用curl调用引发异常的endpoint效果很好,我通过以下示例获得了预期结果:
{
"timestamp": 1494185397677,
"status": 400,
"error": "Bad Request",
"exception": "com.example.exception.AuthenticationException",
"message": "These are not the credentials you are looking for",
"path": "/status/throw/2"
}
当我使用Mockito编写测试时,它使用will Throw()
我没有得到Spring Boot生成的任何输出,而只是在我的异常类中注释的响应代码。
这是我的测试:
@Test
public void throwsShouldShowResponseBody() throws Exception {
given(this.service.getAccStatus())
.willThrow(AuthenticationException.class);
this.mvc.perform(get("/status/throw/2"))
.andExpect(status().isBadRequest())
.andDo(document("bad-credentials"));
}
看看类似的问题,这可能是因为MockMvc没有遵循我认为Spring Boot用于推送/出错的重定向,但我的问题是,如果有任何方法,我可以做到这一点,这样我就不必编写类似于Spring Boot已经提供的错误属性的类。我不希望更改Spring Boot在出现错误时生成的输出。
谢谢-
package com.cts.skynews.springboot.controller;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest {
private static final Logger LOGGER = LoggerFactory.getLogger(UserControllerTest.class);
@Autowired
private WebApplicationContext webApplicationContext;
private MockMvc mockMvc;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
@Test
public void addNewUser() throws Exception {
LOGGER.info("START : Inside Spring Boot addUser() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"kirasln@gmail.com\","
+ "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"},"
+ "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().isOk()).andExpect(jsonPath("$.signedUp").value("true"));
LOGGER.info("END : Spring Boot addUser() method of UserController");
}
@Test
public void checkEmailExists() throws Exception {
LOGGER.info("START : Inside Spring Boot checkEmailExists() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"ravariakiran@gmail.com\","
+ "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"},"
+ "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().isOk()).andExpect(jsonPath("$.emailExists").value("true"))
.andExpect(jsonPath("$.signedUp").value("false"));
LOGGER.info("END : Spring Boot checkEmailExists() method of UserController");
}
@Test
public void incorrectEmailFormat() throws Exception {
LOGGER.info("START : Inside Spring Boot incorrectEmailFormat() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"rgmail.com\"," + "\"password\":\"A123456\","
+ "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Email address is invalid"));
LOGGER.info("END : Spring Boot incorrectEmailFormat() method of UserController");
}
@Test
public void nullName() throws Exception {
LOGGER.info("START : Inside Spring Boot nullName() method of UserController");
String USER_DATA = "{\"email\":\"abcdefg@gmail.com\"," + "\"password\":\"A123456\"," + "\"status\":\"active\","
+ "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Name cannot be empty"));
LOGGER.info("END : Spring Boot nullName() method of UserController");
}
@Test
public void nullPassword() throws Exception {
LOGGER.info("START : Inside Spring Boot nullPassword() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"abcdefg@gmail.com\","
+ "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Password cannot be empty"));
LOGGER.info("END : Spring Boot nullPassword() method of UserController");
}
@Test
public void nullEmail() throws Exception {
LOGGER.info("START : Inside Spring Boot nullEmail() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"password\":\"A123456\"," + "\"status\":\"active\","
+ "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Email cannot be empty"));
LOGGER.info("END : Spring Boot nullEmail() method of UserController");
}
@Test
public void nullStatus() throws Exception {
LOGGER.info("START : Inside Spring Boot nullEmail() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"abcdefg@gmail.com\","
+ "\"password\":\"A123456\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Status cannot be empty"));
LOGGER.info("END : Spring Boot nullStatus() method of UserController");
}
@Test
public void langugaeNull() throws Exception {
LOGGER.info("START : Inside Spring Boot langugaeNull() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"abcdefg@gmail.com\","
+ "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Language cannot be empty"));
LOGGER.info("END : Spring Boot langugaeNull() method of UserController");
}
@Test
public void roleNull() throws Exception {
LOGGER.info("START : Inside Spring Boot roleNull() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"abcdefg@gmail.com\","
+ "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Role cannot be empty"));
LOGGER.info("END : Spring Boot roleNull() method of UserController");
}
@Test
public void invalidNameLength() throws Exception {
LOGGER.info("START : Inside Spring Boot invalidNameLength() method of UserController");
String USER_DATA = "{\"name\":\"KiranKiranRavariyKiranKiranRavariyaRRavariyaRavariyaRavariyaRavariyaRavariya "
+ "KiranKiranRavariyKiranKiranRavariyaRRavariyaRavariyaRavariyaRavariyaRavariya "
+ "KiranKiranRavariyKiranKiranRavariyaRRavariyaRavariyaRavariyaRavariyaRavariya\","
+ "\"email\":\"abcdefg@gmail.com\"," + "\"password\":\"A123456\"," + "\"status\":\"active\","
+ "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError())
.andExpect(jsonPath("$.errorMessage").value("Input Validation Failed:Name must be 3 to 80 characters"));
LOGGER.info("END : Spring Boot invalidNameLength() method of UserController");
}
@Test
public void invalidEmailLength() throws Exception {
LOGGER.info("START : Inside Spring Boot invalidEmailLength() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\","
+ "\"email\":\"ravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmailravariakiran@gmail.com\","
+ "\"password\":\"A123456\"," + "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"},"
+ "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError()).andExpect(
jsonPath("$.errorMessage").value("Input Validation Failed:Email must be 4 to 80 characters"));
LOGGER.info("END : Spring Boot invalidEmailLength() method of UserController");
}
@Test
public void incorrectPasswordFormat() throws Exception {
LOGGER.info("START : Inside Spring Boot incorrectPasswordFormat() method of UserController");
String USER_DATA = "{\"name\":\"Kiran Ravariya\"," + "\"email\":\"abcdefg@gmail.com\"," + "\"password\":\"12\","
+ "\"status\":\"active\"," + "\"language\":{\"id\":\"1\"}," + "\"role\":{\"id\":1}}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/signup").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().is4xxClientError()).andExpect(jsonPath("$.errorMessage")
.value("Input Validation Failed:Password must be 6 to 45 characters"));
LOGGER.info("END : Spring Boot incorrectPasswordFormat() method of UserController");
}
@Test
public void successfullLogin() throws Exception {
LOGGER.info("START : Inside Spring Boot successfullLogin() method of UserController");
String USER_DATA = "{\"email\":\"kiran@gmail.com\",\"password\":\"A123456\"}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/login").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().isOk()).andExpect(jsonPath("$.authenticated").value("true"));
LOGGER.info("END : Spring Boot successfullLogin() method of UserController");
}
@Test
public void invalidEmailForLogin() throws Exception {
LOGGER.info("START : Inside Spring Boot invalidEmailForLogin() method of UserController");
String USER_DATA = "{\"email\":\"kiran123@gmail.com\",\"password\":\"A123456\"}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/login").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().isOk()).andExpect(jsonPath("$.authenticated").value("false"));
LOGGER.info("END : Spring Boot invalidEmailForLogin() method of UserController");
}
@Test
public void invalidPasswordForLogin() throws Exception {
LOGGER.info("START : Inside Spring Boot invalidPasswordForLogin() method of UserController");
String USER_DATA = "{\"email\":\"kiran@gmail.com\",\"password\":\"12345678\"}";
LOGGER.debug("JSON Object : {}", USER_DATA);
mockMvc.perform(post("/user/login").content(USER_DATA).contentType("application/json;charset=UTF-8"))
.andExpect(status().isOk()).andExpect(jsonPath("$.authenticated").value("false"));;
LOGGER.info("END : Spring Boot invalidPasswordForLogin() method of UserController");
}
}
正如您所指出的,在使用MockMvc
时记录Spring Boot的错误响应有点棘手。这是因为Spring Boot将请求转发到映射到/error
的错误控制器,并且MockMvc
默认情况下不处理转发。
记录错误响应的一种方法是使用适当配置的请求直接调用/error
。Spring REST Docs的一个示例中有一个这样的示例:
@Test
public void errorExample() throws Exception {
this.mockMvc
.perform(get("/error")
.requestAttr(RequestDispatcher.ERROR_STATUS_CODE, 400)
.requestAttr(RequestDispatcher.ERROR_REQUEST_URI, "/notes")
.requestAttr(RequestDispatcher.ERROR_MESSAGE, "The tag 'http://localhost:8080/tags/123' does not exist"))
.andExpect(status().isBadRequest())
.andExpect(jsonPath("error", is("Bad Request")))
.andExpect(jsonPath("timestamp", is(notNullValue())))
.andExpect(jsonPath("status", is(400)))
.andExpect(jsonPath("path", is(notNullValue())))
.andDo(this.documentationHandler.document(
responseFields(
fieldWithPath("error").description("The HTTP error that occurred, e.g. `Bad Request`"),
fieldWithPath("message").description("A description of the cause of the error"),
fieldWithPath("path").description("The path to which the request was made"),
fieldWithPath("status").description("The HTTP status code, e.g. `400`"),
fieldWithPath("timestamp").description("The time, in milliseconds, at which the error occurred"))));
}
然后在生成的文档中使用它来描述整个API中使用的错误响应格式。
我试图在spring boot 2.3项目中使用JUnit5与Hibernate5.4和MockMvc。 这就是我的实体类的成员的外观: 我试图使用JUnit5用Mockito和MockMvc测试LocalDate字段birthDate。这就是测试用例的样子: 运行测试用例时,我得到一个AssertionError: 正如您所看到的,这两个字符串表示形式是相同的。但是JUnit5会抛出错误。 那么
我想验证具有字符串属性和字符串值的元素: 我使用了: 它说内容无效。 文档中说,具有属性的元素总是“complexType”。如果省略xs:restriction行,则内容必须为空。但我想要一个字符串值(“eric”)。 XSD代码应该是什么? 附言:我想避免丑陋的“mixed=“true”
我已成功将图像文件上载到。但是我在使用MockMvc测试时遇到了一个问题。当我运行测试用例时,我发现异常文件未找到,访问被拒绝。 控制器看起来像这样: 我的测试用例如下所示: 我的jsp文件如下所示:
我正在使用spring MockMVC测试spring rest控制器。我能够执行模拟http请求并验证响应。我的设置自动连接WebApplicationContext: 为了告诉MockMVC要初始化哪些控制器并将其添加到上下文中,我有一个内部配置类: 这就像一种魅力。MockMVC启动了一个容器,其中包含加载MyRestController的上下文,并为MyRestController映射的U
当我运行测试时,我会得到以下错误(找不到令牌或令牌为空): 我找到了一个暂时的解决方法,但它不是一个好的解决方法…
我试图用以下代码测试Spring MVC控制器的错误响应 但是测试失败,异常是:。 当我卷曲这个URL时,我得到以下信息: 有人能帮我理解我做错了什么吗?