Tout d'abord, créez un simple Controller
comme celui-ci:
«TodoService» n'est pas important dans cet article, je vais donc l'omettre.
Controller.java
@RestController
@RequestMapping("todos")
public class TodoRestController {
@Inject
TodoService todoService;
@Inject
Mapper beanMapper;
@RequestMapping(method = RequestMethod.GET)
@ResponseStatus(HttpStatus.OK)
public List<TodoResource> getTodos() {
Collection<Todo> todos = todoService.findAll();
List<TodoResource> todoResources = new ArrayList<>();
for (Todo todo : todos) {
todoResources.add(beanMapper.map(todo, TodoResource.class));
}
return todoResources;
}
@RequestMapping(method = RequestMethod.POST)
@ResponseStatus(HttpStatus.CREATED)
public TodoResource postTodos(@RequestBody @Validated TodoResource todoResource) {
Todo createdTodo = todoService.create(beanMapper.map(todoResource, Todo.class));
TodoResource createdTodoResponse = beanMapper.map(createdTodo, TodoResource.class);
return createdTodoResponse;
}
}
Écrivons un code de test pour Controller
en utilisant MockMVC.
Test.java
@RunWith(SpringRunner.class)
@ContextHierarchy({@ContextConfiguration({"classpath:META-INF/spring/applicationContext.xml"}),
@ContextConfiguration({"classpath:META-INF/spring/spring-mvc-rest.xml"})})
@WebAppConfiguration
public class TodoRestControllerTest {
@Autowired
WebApplicationContext webApplicationContext;
MockMvc mockMvc;
ObjectMapper mapper;
@Before
public void setup() {
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext)
.addFilter(new XTrackMDCPutFilter(), "/**").alwaysDo(log()).build();
mapper = new ObjectMapper();
}
@Test
public void notExistPathTest() throws Exception {
String title = "title";
TodoResource todoRequest = new TodoResource();
todoRequest.setTodoTitle(title);
MvcResult result = mockMvc
.perform(
MockMvcRequestBuilders.post("/hage").content(mapper.writeValueAsString(todoRequest))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isNotFound()).andReturn();
}
}
Le chemin est / todos
, donc si vous faites une demande à / hage
, vous devriez obtenir 404, mais lorsque vous exécutez le test ...
java.lang.AssertionError: Status expected:<404> but was:<200>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:665)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at todo.api.TodoRestControllerTest.notExistPathTest(TodoRestControllerTest.java:75)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Ce sera 200 pour une raison quelconque. : en pensant:
En passant, si vous déployez sur le serveur AP et envoyez une requête à / hage
, ce sera 404 comme prévu.
Je n'ai pas du tout compris la cause, mais j'ai remarqué que j'avais défini <mvc: default-servlet-handler />
dans le spring-mvc-rest.xml
chargé dans la classe de test. ..
Il s'agit d'un paramètre qui permet à la fonction de transférer la requête reçue par DispatcherServlet
vers le servlet par défaut.
Autrement dit, si vous faites une demande vers un chemin qui n'existe pas, MockMVC la transmettra au servlet par défaut. Étant donné que la destination de transfert est sous la juridiction du serveur AP, ** MockMVC a renvoyé 200 car la transmission a réussi **.
Donc, si vous supprimez <mvc: default-servlet-handler />
, vous récupérerez 404.
Cependant, dans le cas d'applications d'écran qui ne sont pas l'API REST, si la fonction de transfert est désactivée, le fichier statique placé sur le serveur AP ne peut pas être référencé, le code d'état est donc 200 et transmet comme indiqué ci-dessous. Assurez-vous que la destination est le chemin par défaut.
MvcResult result = mockMvc
.perform(
MockMvcRequestBuilders.post("/hage").content(mapper.writeValueAsString(todoRequest))
.contentType(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk()).andExpect(forwardedUrl("default")).andReturn();
}
c'est tout.
Pour le servlet par défaut, l'article Comprendre l'accès aux ressources statiques sur Spring MVC (+ Spring Boot) est facile à comprendre.
Recommended Posts