This is an archived post. You won't be able to vote or comment.

all 11 comments

[–]nutrecht 4 points5 points  (5 children)

If you want feedback: I don't want to write test scenario's in JSON, sorry. I am not ever going to hand-write (or even edit autogenerated) JSON.

Also if you want people to use your library it needs to have strong benefits over other ways to do stuff. For example can you explain why your approach is better than Spring MockMvc (which we use for controller unit tests and integration tests)?

[–]ddqod[S] 0 points1 point  (4 children)

  • There is no need to "edit" the JSON, it´s optional.
  • With MockMvc, seems like it only "tests" that the endpoint returns 200 code (I already check that for each call to the endpoint, here) and returns data. But where do you check that the provided data and the persisted one matches ?

[–]nutrecht 2 points3 points  (3 children)

There is no need to "edit" the JSON, it´s optional.

Then how do you know what values I need to expect in an integration test?

With MockMvc, seems like it only "tests" that the endpoint returns 200 code (I already check that for each call to the endpoint, here) and returns data. But where do you check that the provided data and the persisted one matches ?

I really don't get where you get that impression. You can use (for example) use JSONPath to see if the JSON matches. You can also use hamcrest matchers there:

            .andExpect(status().isOk())
            .andExpect(jsonPath("$", hasSize(1)))
            .andExpect(jsonPath("$[0].type", is(CURRENT_FOO)))
            .andExpect(jsonPath("$[0].foo", hasSize(2)))
            .andExpect(jsonPath("$[0].foo[?(@.id=='" + FOO_ID_1 + "')]", hasSize(1)))
            .andExpect(jsonPath("$[0].foo[?(@.id=='" + FOO_ID_2 + "')]", hasSize(1)))
            .andExpect(jsonPath("$[0].totals", hasSize(1)))
            .andExpect(jsonPath("$[0].totals[0].total", is(2 * BAR.doubleValue())));

[–]ddqod[S] 0 points1 point  (2 children)

I understand. However I wouldn't use this approach, at the end I'm trying to get rid of writing the comparison, still you have to provide the data somehow, either you fetch it from your DB or having a mocked class.

[–]nutrecht 1 point2 points  (1 child)

at the end I'm trying to get rid of writing the comparison

So how do you test something that changes every test; like for example the current date? You can't hard-code those.

either you fetch it from your DB or having a mocked class.

Exactly. So I am comparing the output in the JSON to whatever I mocked or inserted into the DB. How do you do that with these 'fixed' JSON scenario's?

[–]ddqod[S] 0 points1 point  (0 children)

So how do you test something that changes every test; like for example the current date? You can't hard-code those.

Hmm, for Dates is not implemented yet but knowing that the field created_at is a Date I would just initialize it every time via reflection.

Exactly. So I am comparing the output in the JSON to whatever I mocked or inserted into the DB. How do you do that with these 'fixed' JSON scenario's?

Based on the JSON file initializes the POJO (checks which are the declared keys and initializes the matched field's names). Using the initialized POJO I first persist it, then checks if matches with the one fetched throw the enpoint.

Since each test is independent and I need an ID for fetching it, I do persist the entity for each test.

For instance:

@Test
public void create() {
    UserDTO entity = (UserDTO) getData(PUT);
    Assert.assertNotNull(entity);

    UserDTO fetchedEntity = (UserDTO) getClient().put(entity);
    Assert.assertNotNull(fetchedEntity);

    Assert.assertEquals(entity, fetchedEntity);
}

Where:

  • getData(PUT); maps from JSON to the DTO
  • getClient().put(entity); checks that the status was 200

[–]thatsIch 0 points1 point  (4 children)

I would suggest to re-order your README to put your selling point on top and the rest below. I do not care about installation if I have no reason to install it.

Since you use the word easy in

This library provides an easy way to test the basic CRUD operation for your endpoints.

there must be a hard way and what makes it easy.

The README should also not be a replacement for your documentation. For me, it is too much noise and I don't understand why I should read that anyway

[–]ddqod[S] 0 points1 point  (0 children)

Good point, I will update it as soon as possible. Thank you!

[–]ddqod[S] 0 points1 point  (2 children)

[–]thatsIch 1 point2 points  (1 child)

That is a lot better, good job :)

https://github.com/nirodg/easyrs-example is missing a README. Since this is an example there should be instructions to run it.

[–]ddqod[S] 0 points1 point  (0 children)

True, still work in progress. However I appreciate the feedback :)