web-dev-qa-db-ja.com

junitテストでのMockMVC-List <Object>およびMap <Enum、Object>の結果の確認

MockMVCとそれで書かれたテストに問題があります。私のテストは失敗します。私には2つのテスト方法があります:

@Test
public void getPersonsForApiConsumerTest() throws Exception {
    mockMvc.perform(get(getUri("/consumers/1/persons")))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$", hasSize(2)))
            .andExpect(jsonPath("$[1].name", is("Ligza")))
            .andExpect(jsonPath("$[2].name", is("Vekrir")));

}

@Test
public void getPersonsForApiConsumerMapTest() throws Exception {
    mockMvc.perform(get(getUri("/consumers/1/persons/map")))
            .andExpect(status().isOk())
            .andExpect(jsonPath("$[1].name", is("Verkir")))
            .andExpect(jsonPath("$[2].name", is("Ligza")));
}

マッピングを使用したRESTメソッド:

 @RequestMapping(value = "/{consumerId}/persons")
    public List<PersonDto> getPersonsForApiConsumer(@PathVariable("consumerId") Integer consumerId) throws IOException {
        return apiConsumerService.getPersonsListForApiConsumer(consumerId);
    }

    @RequestMapping(value = "/{consumerId}/persons/map")
    public Map<ApiConsumerPersonRole, List<Person>> getPersonsForApiConsumerMap(@PathVariable("consumerId") Integer consumerId) throws IOException {
        return apiConsumerService.getPersonsMapForApiConsumer(consumerId);
    }

Postmanによって、次のようなデータを取得できます。

リストの場合:

[
    {
        "id": 1,
        "firstName": "Ligza",
        "lastName": "Zetasor",
        "role": "REPRESENTATIVE",
        "phone": "123123123",
        "email": "[email protected]"
    },
    {
        "id": 4,
        "firstName": "Vekrir",
        "lastName": "Omegaram",
        "role": "SECURITY_OFFICER",
        "phone": "354654545",
        "email": "[email protected]"
    }
]

マップの場合:

{
    "SECURITY_OFFICER": [
        {
            "id": 4,
            "firstName": "Vekrir",
            "lastName": "Omegaram",
            "telephone": "354654545",
            "email": "[email protected]"
        }
    ],
    "REPRESENTATIVE": [
        {
            "id": 1,
            "firstName": "Ligza",
            "lastName": "Zetasor",
            "telephone": "123123123",
            "email": "[email protected]"
        }
    ],
    "COMPLAINT_OFFICER": [],
    "LOCAL_REPRESENTATIVE": []
}

私はそれを正しく書く方法の手がかりを持っていません。このリストとマップ内のデータを確認したいと思います。

それをそのコレクションにストリーミングしたり、すでに書かれている方法で簡単にチェックしたりすることは可能ですか?


編集:ログ:

Java.lang.AssertionError: No value at JSON path "$[1].firstname", exception: No results for path: $[1]['firstname']

    at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.Java:245)
    at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.Java:73)
    at org.springframework.test.web.servlet.result.JsonPathResultMatchers$1.match(JsonPathResultMatchers.Java:87)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.Java:171)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    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.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.junit.runner.JUnitCore.run(JUnitCore.Java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.Java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.Java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.Java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.Java:70)


Process finished with exit code -1

MockHttpServletResponse:
           Status = 200
    Error message = null
          Headers = {X-Content-Type-Options=[nosniff], X-XSS-Protection=[1; mode=block], Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], Pragma=[no-cache], Expires=[0], X-Frame-Options=[DENY], Content-Type=[application/json;charset=UTF-8]}
     Content type = application/json;charset=UTF-8
             Body = {"COMPLAINT_OFFICER":[],"REPRESENTATIVE":[{"id":1,"firstName":"Ligza","lastName":"Zetasor","telephone":"123123123","email":"[email protected]"}],"LOCAL_REPRESENTATIVE":[],"SECURITY_OFFICER":[{"id":4,"firstName":"Vekrir","lastName":"Omegaram","telephone":"354654545","email":"[email protected]"}]}
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

Java.lang.AssertionError: No value at JSON path "$[1].firstname", exception: Filter: [1]['firstname'] can only be applied to arrays. Current context is: {COMPLAINT_OFFICER=[], REPRESENTATIVE=[{"id":1,"firstName":"Ligza","lastName":"Zetasor","telephone":"123123123","email":"[email protected]"}], LOCAL_REPRESENTATIVE=[], SECURITY_OFFICER=[{"id":4,"firstName":"Vekrir","lastName":"Omegaram","telephone":"354654545","email":"[email protected]"}]}

    at org.springframework.test.util.JsonPathExpectationsHelper.evaluateJsonPath(JsonPathExpectationsHelper.Java:245)
    at org.springframework.test.util.JsonPathExpectationsHelper.assertValue(JsonPathExpectationsHelper.Java:73)
    at org.springframework.test.web.servlet.result.JsonPathResultMatchers$1.match(JsonPathResultMatchers.Java:87)
    at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.Java:171)
    at Sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at Sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.Java:62)
    at Sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.Java:43)
    at Java.lang.reflect.Method.invoke(Method.Java:498)
    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.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.junit.runner.JUnitCore.run(JUnitCore.Java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.Java:68)
    at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.Java:47)
    at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.Java:242)
    at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.Java:70)
5
xross

jsonPathヘルパーは、APIのコンシューマーの観点から応答が有効であると主張するのに非常に役立ちます。これらのコンシューマーはJSON応答を受け取るため、そのJSONでアサーションを実行することは理にかなっています。

次のアサーションは、/consumers/1/personsからのペイロードに対して機能します。

.andExpect(jsonPath("$[0].firstName", is("Ligza")))
.andExpect(jsonPath("$[1].firstName", is("Vekrir")))

したがって、配列は0ベースであり、(大文字と小文字を区別する)名前で各要素のエントリにアクセスします。

ただし、実際に元の型(PersonDtoなど)に対してアサートする場合は、JSON文字列全体を読み取り、JSONマッパー( Jacksonなど)を使用できます。 Gson )を逆シリアル化して、元のクラス表現に戻します。例えば:

MvcResult result = mockMvc.perform(get(getUri("/consumers/1/persons")))
        .andExpect(status().isOk())
        .andReturn();

ObjectMapper mapper = new ObjectMapper();

// this uses a TypeReference to inform Jackson about the Lists's generic type
List<PersonDto> actual = mapper.readValue(result.getResponse().getContentAsString(), new TypeReference<List<PersonDto>>() {});

// now just assert equality (or whatever) against the actual PersonDto
16
glytching