3

Suppose I want to create a unit test for a method like this:

public Car map(CarReq request) {

    Car car = new Car();
    car.setPrice(carReq.getPrice());
    car.setColour(carReq.getColour());
    car.setType(carReq.getType());

    // Other 20 lines like these

    return car;
}

I can mock carRequest and tell each method what should return. But that's like not testing anything, as all the method does is getting values from carReq.

I can create a testing carReq object (without mocking) and check that the same values are copied into the output Car object. But that's a lot of work, right?

Isn't there a more intelligent way?

user1883212
  • 7,539
  • 11
  • 46
  • 82

3 Answers3

6

You want to test the logic of the method.

Therefore if what the method does is copying the properties of a CarReq into a Car, then this is what you should test:

@Test
public void mapTest() {
    // Given
    CarReq carReq = new CarReq(10000D, ...);

    // When
    Car car = myClass.map(carReq);

    // Then
    Assert.assertEquals(car.getPrice(), carReq.getPrice());
    // ...
}
Jean Logeart
  • 52,687
  • 11
  • 83
  • 118
  • But if car.getPrice() fails or carReq.getPrice() fails, then the test would fail, while map() could be OK. So ideally there need to be mock methods for car.getPrice() fails or carReq.getPrice(). Is the above approach a good one because usually the getters don't need to be tested? – Treefish Zhang Nov 14 '17 at 22:11
0

I'm not quite sure what the issue is ? Surely since the method takes a request and returns a new Car, that's precisely what you want to test ? If I was doing it, I would:

  1. create a populated request and determine that the Car fields are what are in the request
  2. perhaps assert that each invocation gives you a new Car ?
  3. assert expected behaviour if you pass in a null (again, depending on the proposed usage of the method)

You say that all the method does is call setters/getters, but don't forget that one purpose of a unit test is to assert that the behaviour remains the same going forwards (i.e. you're testing for regressions). If you add additional functionality to this method, and you accidentally break something, the above test will tell you immediately.

Is it a lot of work ? Maybe (perhaps a few mins of copy/paste getter/setter invocations and changing params to be unique per attribute). But it's a lot less work than resolving an issue in production later on.

Brian Agnew
  • 268,207
  • 37
  • 334
  • 440
0

I can create a testing carReq object (without mocking) and check that the same values are copied into the output Car object. But that's a lot of work, right?

It is, but if you really are willing to unit-test this method, you have to do this. Please note that you can use libraries like Orika to perform this kind of dumb field-mapping methods for you. Saves time and code lines :)

matthieu.cham
  • 501
  • 5
  • 17