Jacek
Jacek

Reputation: 39

AssertionError: No value at JSON path, but value exists in valid JSON response

I saw many of solutions provided here, on the forum, and also a guide for the problem (provided here), but none of them helped me...

I tried to keep my code cleare as much as I can, so I decided to create many of test classes including test items, for example:

@Getter
@Setter
public class SalesTaskTestItem {

    public static SalesTask buildTestItem(){

        List<ContactPerson> contactPersonTestItemList = new ArrayList<>();
        contactPersonTestItemList.add(ContactPersonTestItem.buildTestItem());

        List<SalesMan> supportingSalesTeamList = new ArrayList<>();

        List<Product> discussedProductsTestList = new ArrayList<>();
        discussedProductsTestList.add(ProductTestItem.buildTestItem());

        List<SalesTaskProgress> progressTestList = new ArrayList<>();
        progressTestList.add(SalesTaskProgressTestItem.buildTestItemNo1());
        progressTestList.add(SalesTaskProgressTestItem.buildTestItemNo2());
        progressTestList.add(SalesTaskProgressTestItem.buildTestItemNo3());

        List<Offer> alreadySentOffersTestList = new ArrayList<>();
        alreadySentOffersTestList.add(OfferTestItem.buildTestItem());

        List<AssignedTaskDocument> assignedTaskDocumentsTestList = new ArrayList<>();
        assignedTaskDocumentsTestList.add(AssignedTaskDocumentTestItem.buildTestItem());

        List<InternalProcedureDocument> internalProceduresDocumentsTestList = new ArrayList<>();
        internalProceduresDocumentsTestList.add(InternalProcedureDocumentTestItem.buildTestItem());


        SalesTask testItem = new SalesTask();
        testItem.setId(1L);
        testItem.setVersion(1);
        testItem.setTaskEstablishedDate(DateFormatter.fromStringToDate("10-12-2020T09:12:45"));
        testItem.setLastProgressDate(DateFormatter.fromStringToDate("10-12-2020T09:30:56"));
        testItem.setCompany(CompanyTestItem.buildTestItem());
        testItem.setContactPersonsList(contactPersonTestItemList);
        testItem.setMainSalesMan(SalesManTestItem.buildTestItemNo1());
        testItem.setSupportingSalesTeam(supportingSalesTeamList);
        testItem.setDiscussedProducts(discussedProductsTestList);
        testItem.setProgressList(progressTestList);
        testItem.setCurrentTaskValue(BigDecimal.valueOf(250000));
        testItem.setChanceOfPositiveFinishingTask(0.45);
        testItem.setEstimatedDateOfFinishingTask(DateFormatter.fromStringToDate("30-12-2020T13:00:00"));
        testItem.setAlreadySentOffersList(alreadySentOffersTestList);
        testItem.setAssignedTaskDocumentsList(assignedTaskDocumentsTestList);
        testItem.setInternalProceduresDocumentsList(internalProceduresDocumentsTestList);
        return testItem;
    }

}

My test case is:

package com.jmdev.storycrm.controllers;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.jmdev.storycrm.domain.salesTask.SalesTask;
import com.jmdev.storycrm.services.SalesTaskService;
import com.jmdev.storycrm.testDomainItems.salesTask.SalesTaskTestItem;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;

@ExtendWith(SpringExtension.class)
@WebMvcTest

public class SalesTaskControllerTest {

    @Autowired
    MockMvc mockMvc;

    @MockBean
    private SalesTaskService salesTaskService;


    @Test
    public void createNewSalesTask(){

        SalesTask newSalesTask = new SalesTask();
        newSalesTask = SalesTaskTestItem.buildTestItem();

        when(salesTaskService.save(any(SalesTask.class))).thenReturn(newSalesTask);

        ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());

        try {
            String newSalesTaskJSON = objectMapper.writeValueAsString(newSalesTask);

            ResultActions resultActions = mockMvc.perform(
                    post("/salesTask")
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(newSalesTaskJSON)
            );

            resultActions.andExpect(status().isCreated())
                    .andDo(print())
                    .andExpect(content().contentType("application/json"))
                    .andExpect(jsonPath("$.id").value(1L))
                    .andExpect(jsonPath("$.version").value(1))
                    .andExpect(jsonPath("$.taskEstablishedDate").value(SalesTaskTestItem.buildTestItem().getTaskEstablishedDate().toString()))
                    .andExpect(jsonPath("$.lastProgressDate").value(SalesTaskTestItem.buildTestItem().getLastProgressDate().toString()))
                    .andExpect(jsonPath("$.company").value(SalesTaskTestItem.buildTestItem().getCompany()))
                    .andExpect(jsonPath("$.contactPersonsList").value(SalesTaskTestItem.buildTestItem().getContactPersonsList()))
                    .andExpect(jsonPath("$.mainSalesMan").value(SalesTaskTestItem.buildTestItem().getMainSalesMan()))
                    .andExpect(jsonPath("$.supportingSalesTeam").value(SalesTaskTestItem.buildTestItem().getSupportingSalesTeam()))
                    .andExpect(jsonPath("$.discussedProducts").value(SalesTaskTestItem.buildTestItem().getDiscussedProducts()))
                    .andExpect(jsonPath("$.progressList").value(SalesTaskTestItem.buildTestItem().getProgressList()))
                    .andExpect(jsonPath("$.currentTaskValue").value(SalesTaskTestItem.buildTestItem().getCurrentTaskValue()))
                    .andExpect(jsonPath("$.chanceOfPositiveFinishingTask").value(SalesTaskTestItem.buildTestItem().getChanceOfPositiveFinishingTask()))
                    .andExpect(jsonPath("$.estimatedDateOfFinishingTask").value(SalesTaskTestItem.buildTestItem().getEstimatedDateOfFinishingTask()))
                    .andExpect(jsonPath("$.alreadySentOffersList").value(SalesTaskTestItem.buildTestItem().getAlreadySentOffersList()))
                    .andExpect(jsonPath("$.assignedTaskDocumentsList").value(SalesTaskTestItem.buildTestItem().getAssignedTaskDocumentsList()))
                    .andExpect(jsonPath("$.internalProceduresDocumentsList").value(SalesTaskTestItem.buildTestItem().getInternalProceduresDocumentsList()));

        } catch (Exception e) {
            e.printStackTrace();
        }

    }


}

I see in stack trace my MockHttpServletResponse, where I can find "taskEstablishedDate":"2020-12-10T09:12:45.000+00:00". Also, If I copy whole body of this response and past it into https://jsonformatter.curiousconcept.com/, validation is passed with no problems.

MockHttpServletResponse:
           Status = 201
    Error message = null
          Headers = [Content-Type:"application/json"]
     Content type = application/json
             Body = {"id":1,"version":1,"taskEstablishedDate":"2020-12-10T09:12:45.000+00:00","lastProgressDate":"2020-12-10T09:30:56.000+00:00", (...) }
    Forwarded URL = null
   Redirected URL = null
          Cookies = []

But I get java.lang.AssertionError: No value at JSON path "$.taskEstablishedDate".

I really don't know what is wrong. Could anybody help?

EDIT: I implemented SSK suggestions and dates and time are passing now. For test next of JSON values, provided as my app's objects, I implemented GSON into override toString() method:

package com.jmdev.storycrm.domain.company;

import com.jmdev.storycrm.utils.JSONFormatter;
import lombok.Getter;
import lombok.Setter;
import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@Getter
@Setter
public class Company {

    @Id
    private Long id;
    private String name;
    private Long nipNumber;
    private Address address;

    @Override
    public String toString() {
        return JSONFormatter.useGSON(this);
    }   
}

Used toString() formatter:

package com.jmdev.storycrm.utils;

public class JSONFormatter {

    public static String useGSON(Object object){
        return new com.google.gson.Gson().toJson(object);
    }
}

But I'm getting java.lang.AssertionError for both values which are completely the same...

java.lang.AssertionError: JSON path "$.company" (...)
Expected :{"id":1,"name":"TestCompanyName","nipNumber":345353534354335,"address":{"id":1,"voivodeship":"Region name","postalCode":"99-000","city":"My City name","street":"Main Street name","fullBiuldingNumber":"100","flatNumber":1}}
Actual   :{"id":1,"name":"TestCompanyName","nipNumber":345353534354335,"address":{"id":1,"voivodeship":"Region name","postalCode":"99-000","city":"My City name","street":"Main Street name","fullBiuldingNumber":"100","flatNumber":1}} 

Upvotes: 1

Views: 971

Answers (1)

SSK
SSK

Reputation: 3766

You need to register your JavaTimeModule with ObjectMapper.
You can register JavaTimeModule as shown below.

ObjectMapper objectMapper = new ObjectMapper().registerModule(new JavaTimeModule());

Then use the same objectMapper to create the json string

String newSalesTaskJSON = objectMapper.writeValueAsString(newSalesTask);

JavaTimeModule is from com.fasterxml.jackson.datatype.jsr310.JavaTimeModule

Also, you need to add .toString() to your date values in .andExpect() as shown below

.andExpect(jsonPath("$.taskEstablishedDate").value(SalesTaskTestItem.buildTestItem().getTaskEstablishedDate().toString()))
.andExpect(jsonPath("$.lastProgressDate").value(SalesTaskTestItem.buildTestItem().getLastProgressDate().toString()))
.andExpect(jsonPath("$.estimatedDateOfFinishingTask").value(SalesTaskTestItem.buildTestItem().getEstimatedDateOfFinishingTask().toString()))

Upvotes: 2

Related Questions