Lets say we have a class Cat
:
class Cat{
public eat(String food){
if (food.contains("cat")){
burp();
}
}
private burp(){
System.out.println("burp!!");
}
}
And we have the following code to test it (using Mockito and TestNG):
@DataProvider
public Object[][] dataProviderForTestFeedCat() {
return new Object[][] {
{"catfood", true},
{"birdfood", false},
{"dogfood", false},
{"food for cat", true}
};
}
@Test(dataProvider = "dataProviderForTestFeedCat")
public void testFeedCat(String food, boolean shouldBurp){
Cat cat = new Cat();
cat.eat(food)
verify(cat, times(shouldBurp ? 1 : 0)).burp();
}
Someone suggested to me that its better to avoid shouldBurp ? 1 : 0
logic inside the test body and rather than have the count provided by the data provider directly:
@DataProvider
public Object[][] dataProviderForTestFeedCat() {
return new Object[][] {
{"catfood", 1},
{"birdfood", 0},
{"dogfood", 0},
{"food for cat", 1}
};
}
@Test(dataProvider = "dataProviderForTestFeedCat")
public void testFeedCat(String food, int burpCount){
Cat cat = new Cat();
cat.eat(food)
verify(cat, times(burpCount)).burp();
}
Their argument is that the test body itself should be as simple as possible.
But a counter argument would be that the data provider should be simple and should only provide the raw data. It should not care that the test is actually generating an integer out the boolean to verify if a method is called or not.
A boolean also feels more intuitive and natural given that its very unlikely for this particular method to be executed twice in a single invocation in our real code.
What is the better approach?