[JAVA] MockMVC gibt 200 zurück, auch wenn ich eine Anfrage an einen Pfad stelle, der nicht existiert

Betriebsüberprüfungsumgebung

Situation, in der 200 zurückgegeben wird

Erstellen Sie zunächst einen einfachen Controller wie folgt: "TodoService" ist in diesem Artikel nicht wichtig, daher werde ich es weglassen.

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;
    }
}

Schreiben wir einen Testcode für "Controller" mit 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();
  }
}

Der Pfad lautet "/ todos". Wenn Sie also eine Anfrage an "/ hage" stellen, sollten Sie 404 erhalten, aber wenn Sie den Test ausführen ...

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)

Es wird aus irgendeinem Grund 200 sein. : Denken: Übrigens, wenn Sie auf dem AP-Server bereitstellen und eine Anfrage an / hage senden, wird es erwartungsgemäß 404 sein.

Die Ursache ist die Vorwärtsfunktion

Ich habe die Ursache überhaupt nicht verstanden, aber ich habe festgestellt, dass ich "<mvc: default-servlet-handler />" in der in der Testklasse geladenen "spring-mvc-rest.xml" gesetzt habe. ..

Dies ist eine Einstellung, mit der die Funktion die von "DispatcherServlet" empfangene Anforderung an das Standardservlet weiterleiten kann.

Wenn Sie also eine Anforderung an einen nicht vorhandenen Pfad senden, leitet MockMVC diese an das Standardservlet weiter. Da das Weiterleitungsziel der Gerichtsbarkeit des AP-Servers unterliegt, hat ** MockMVC 200 zurückgegeben, da die Weiterleitung erfolgreich war **. Wenn Sie also "<mvc: default-servlet-handler />" entfernen, erhalten Sie 404 zurück.

Bei Bildschirmanwendungen, die keine REST-API sind, kann auf die auf dem AP-Server abgelegte statische Datei nicht verwiesen werden, wenn die Weiterleitungsfunktion deaktiviert ist. Daher lautet der Statuscode 200 und weiter wie unten gezeigt. Stellen Sie sicher, dass das Ziel der Standardpfad ist.

    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();
  }

das ist alles.

abschließend

Für das Standardservlet ist der Artikel Grundlegendes zum Zugriff auf statische Ressourcen in Spring MVC (+ Spring Boot) leicht zu verstehen.

Recommended Posts

MockMVC gibt 200 zurück, auch wenn ich eine Anfrage an einen Pfad stelle, der nicht existiert
Wenn in Ruby Hash [: a] [: b] [: c] = 0 ist, möchten wir, dass Sie rekursiv erweitern, auch wenn der Schlüssel nicht vorhanden ist
So funktioniert @Transactional, das nicht funktioniert, wenn Sie es falsch verwenden
Ich möchte das Flash-Attribut im Frühjahr, auch wenn ich einen Reverse-Proxy festgelegt habe! (TU es nicht)
So identifizieren Sie den Pfad, auf dem leicht Fehler gemacht werden können
Eine Geschichte, die selbst ein Mann, der die C-Sprache nicht versteht, Ruby 2.6 um neue Funktionen erweitern könnte
So interagieren Sie mit einem Server, der die App nicht zum Absturz bringt
Ich habe versucht, eine Web-API zu erstellen, die mit Quarkus eine Verbindung zur Datenbank herstellt
Eine Geschichte, die unter einem Raum litt, der nicht verschwindet, selbst wenn er mit Java beschnitten ist
Eine Notiz, die ich aufgegeben habe, um eine benutzerdefinierte Anmerkung für Lombok zu erstellen
[JPA] Vergleichen Sie Tabelle1 und Tabelle2, um Daten abzurufen und zu aktualisieren, die in Tabelle2 nicht vorhanden sind
Einstellungsmethode, die die Größe nicht ändert, auch wenn das CSS geändert wird
Selbst in Java möchte ich true mit == 1 && a == 2 && a == 3 ausgeben (graue Magie, die weniger schwarze Magie ist)
Ich habe Java gemacht, um (a == 1 && a == 2 && a == 3) immer wahr zu machen
Ich wollte (a == 1 && a == 2 && a == 3) in Java wahr machen
Ich habe versucht, einen neuen Sortieralgorithmus zu erstellen, aber ich weiß nicht, ob er wirklich neu ist
[Java] Umgang mit der Situation, in der das Programm, das in den Output Stream of Process schreibt, nicht endet, selbst wenn waitFor
Ich habe versucht, eine Anmeldefunktion mit Java zu erstellen
[Java] Ich habe versucht, ein Janken-Spiel zu erstellen, das Anfänger auf der Konsole ausführen können
Es ist keine große Sache, wenn Sie verstehen, dass ich süchtig danach war, E-Mails mit Java Mail von Exchange Online zu empfangen