Search code examples
javaspringmongodbhttp

How to get mongodb objectId from HTTP response


I am testing an endpoint that saves an object in the database. Post method works as intended and object goes to database. I am trying to figure out how to get the mongo objectID from the HTTP response I get so I can make further tests with Put and Delete methods since I need the objectId for the URI.

@Test
public void saveRule() throws URISyntaxException, IOException {

    RuleDTO ruleDTO = new RuleDTO();
    ruleDTO.setTitle("My rule");
    ruleDTO.setIndex(666);

    ObjectMapper mapper = new ObjectMapper();
    String json = mapper.writeValueAsString(ruleDTO);

    String target = "http://localhost:8090" + "/v2/rules"; // fix
    URI uri = new URI(target);
    HttpPost httpPost = new HttpPost(uri.toASCIIString());
    StringEntity entity = new StringEntity(json);
    httpPost.setHeader("Accept", "application/json");
    httpPost.setHeader("Content-type", "application/json");
    httpPost.setEntity(entity);
    HttpResponse response = httpClient.execute(httpPost);

    int HTTPcode = response.getStatusLine().getStatusCode();
    HttpEntity getEntity = response.getEntity();
    String getJson = EntityUtils.toString(getEntity);

    ObjectMapper objectMapper = new ObjectMapper();
    Rule rule = objectMapper.readValue(getJson, Rule.class);
    boolean isMyRule = false;

    if (rule.getTitle().equals("My rule")) {
        isMyRule = true;
    }

    boolean correctStatus = HTTPcode >= 200 && HTTPcode <= 300 ? true : false;

    assertTrue(correctStatus);
    assertTrue(isMyRule);
}

Solution

  • Given that you said that the test is for an endpoint, this answer is assuming it to be an end-to-end test rather than a unit test. Here are some things you could try:

    1. Usually most of the REST APIs, on making a POST request to add a record, return the key of the record that got added. If you have the option to change the service, maybe you should consider adding this to your service if it doesn't already have. Then, in the test, it will just be a matter of reading the key from the response to the POST request you made, and then using it to make PUT and DELETE requests.
    2. If method (1) is not an option, and if you are sure that you can fetch the record you just added based on the other fields of the record, you can go about making a GET request on the endpoint. Then, iterate on the records that got fetched till you get the key (ObjectId in your case) of the record you just inserted, and use it to make PUT and DELETE requests. It is obvious that this will make the test run much slower, especially when the number of records is high. If there are GET endpoints that filter based on the fields, like - say using query parameters (Eg: /v2/rules?title="Myrule"&index="666"), then that should substantially speed up the test execution and should be used for the GET request.
    3. If the above two methods are not feasible for any reason, and if querying the MongoDB Collection through tests is possible, then, probably the only option left to you is to connect to MongoDB through the test, and then query for the document that you just inserted, get the ObjectId, and use it to make PUT and DELETE requests. This would probably be the most unorthodox way of doing it and is not recommended if you are running the test on the actual database. If, however, you're planning to run it on a mock database, then that's still a way to go.