While I am not entirely new to testing and unit-testing in particular I often hesitate in regards to stuff like the following:
Imagine the following implementation I want to test (yes, I know TDD ftw ;))
private Value0Service value0Service = new Value0Service();
private Value1Service value1Service = new Value1Service();
public SomeInfo readInfo(final Long id, final Value value0, final Value value1) {
final Value1 actualValue0 = fetchValue0IfNullElseReturnGiven(id, value0);
final Value2 actualValue1 = fetchValue1IfNullElseReturnGiven(value1);
return SomeInfo(actualValue0, actualValue1);
}
private Value fetchValue0IfNullElseReturnGiven(Long id, Value value0) {
if(value0== null) {
return value0Service.getById(id);
}
return value0;
}
private Value fetchValue1IfNullElseReturnGiven(Value value0, Value value1) {
if(value1 == null) {
return value1Service.getByValue0(value0);
}
return value1;
}
While this is a constructed example I hope the intent is clear.
Now if I write tests is it enough to cover the behaviour for each "fetch"-method, or should I also cross my tests? What I mean by that:
Do I only assert that my return value of readInfo SomeInfo has the respective parameter set or do I always check for both?
(I am sorry, it's difficult to explain in English) should I interleave my tests like:
// ValueServices are to be treated as mocks from here, so imagine Value0Service value0ServiceMock = mock(Value0Service.class) in the tests!
@Test
public void ifBothValuesAreGivenThenSomeInfoIsFilledWithGivenForBoth() {
Value value0 = new Value();
Value value1 = new Value();
SomeInfo info = myTestObject.readInfo(VALID_ID, value0, value1);
assertThat(info.getValue0()).isEqualTo(value0);
assertThat(info.getValue1()).isEqualTo(value1);
}
@Test
public void ifValue0IsNullAndValue1IsNotThenSomeInfoIsFilledWithFetchedForValue0AndGivenForValue1() {
Value value1 = new Value();
Value fetchedValue0 = new Value();
doReturn(fetchedValue0).when(value0ServiceMock).getById(VALID_ID);
SomeInfo info = myTestObject.readInfo(VALID_ID, null, value1);
assertThat(info.getValue0()).isEqualTo(fetchedValue0);
assertThat(info.getValue1()).isEqualTo(value1);
}
@Test
public void ifValue0IsNotNullAndValue1IsThenSomeInfoIsFilledWithGivenForValue0AndFetchedForValue1() {
Value value0 = new Value();
Value fetchedValue1 = new Value();
doReturn(fetchedValue1).when(value1ServiceMock).getByValue(value0);
SomeInfo info = myTestObject.readInfo(VALID_ID, value0, null);
assertThat(info.getValue0()).isEqualTo(value0);
assertThat(info.getValue1()).isEqualTo(fetchedValue1);
}
@Test
public void ifValue0IsNullAndValue1IsNullThenSomeInfoIsFilledWithFetchedForBoth() {
Value fetchedValue0 = new Value();
Value fetchedValue1 = new Value();
doReturn(fetchedValue0).when(value0ServiceMock).getById(VALID_ID);
doReturn(fetchedValue1).when(value1ServiceMock).getByValue(fetchedValue0);
SomeInfo info = myTestObject.readInfo(VALID_ID, null, null);
assertThat(info.getValue0()).isEqualTo(fetchedValue0);
assertThat(info.getValue1()).isEqualTo(fetchedValue1);
}
Should I always add asserts for both values, or only for one? In both cases I would write 4 tests, so I wonder, because I was told that a good way to handle assertions is to just have one per test, else you're doing something wrong.
Aucun commentaire:
Enregistrer un commentaire