问题
I want to assert that an exception is raised and that the server returns an 500 internal server error.
To highlight the intent a code snippet is provided:
thrown.expect(NestedServletException.class);
this.mockMvc.perform(post("/account")
.contentType(MediaType.APPLICATION_JSON)
.content(requestString))
.andExpect(status().isInternalServerError());
Of course it dosen't matter if I write isInternalServerError
or isOk
.
The test will pass regardless if an exception is thrown below the throw.except
statement.
How would you go about to solve this?
回答1:
You can try something as below -
Create a custom matcher
public class CustomExceptionMatcher extends TypeSafeMatcher<CustomException> { private String actual; private String expected; private CustomExceptionMatcher (String expected) { this.expected = expected; } public static CustomExceptionMatcher assertSomeThing(String expected) { return new CustomExceptionMatcher (expected); } @Override protected boolean matchesSafely(CustomException exception) { actual = exception.getSomeInformation(); return actual.equals(expected); } @Override public void describeTo(Description desc) { desc.appendText("Actual =").appendValue(actual) .appendText(" Expected =").appendValue( expected); } }
Declare a
@Rule
in JUnit class as below -@Rule public ExpectedException exception = ExpectedException.none();
Use the Custom matcher in test case as -
exception.expect(CustomException.class); exception.expect(CustomException .assertSomeThing("Some assertion text")); this.mockMvc.perform(post("/account") .contentType(MediaType.APPLICATION_JSON) .content(requestString)) .andExpect(status().isInternalServerError());
P.S.: I have provided a generic pseudo code which you can customize as per your requirement.
回答2:
You can get a reference to the MvcResult and the possibly resolved exception and check with general junit assertions...
MvcResult result = this.mvc.perform(
post("/api/some/endpoint")
.contentType(TestUtil.APPLICATION_JSON_UTF8)
.content(TestUtil.convertObjectToJsonBytes(someObject)))
.andDo(print())
.andExpect(status().is4xxClientError())
.andReturn();
Optional<SomeException> someException = Optional.ofNullable((SomeException) result.getResolvedException());
someException.ifPresent( (se) -> assertThat(se, is(notNullValue())));
someException.ifPresent( (se) -> assertThat(se, is(instanceOf(SomeException.class))));
回答3:
In your controller:
throw new Exception("Athlete with same username already exists...");
In your test:
try {
mockMvc.perform(post("/api/athlete").contentType(contentType).
content(TestUtil.convertObjectToJsonBytes(wAthleteFTP)))
.andExpect(status().isInternalServerError())
.andExpect(content().string("Athlete with same username already exists..."))
.andDo(print());
} catch (Exception e){
//sink it
}
来源:https://stackoverflow.com/questions/16605811/mockmvc-how-to-test-exception-and-response-code-in-the-same-test-case