Create Junit test for Void method

和自甴很熟 提交于 2021-01-28 20:33:55

问题


I am learning unit testing, I have some confusion, I have one Void method, Can you please explain to me how can I create a unit test for this method.

public void eat(Food food){

mAmountOfEatenFood += food.eatFood(mNeededAmountOfFood - mAmountOfEatenFood);
if(mAmountOfEatenFood == mNeededAmountOfFood){
    System.out.println(mName + " has eaten " + mAmountOfEatenFood + " and will not be hungry for a while..");
    mAmountOfEatenFood = 0;
    mIsHungry = false;  
}else{
    System.out.println(mName + " has eaten " + mAmountOfEatenFood + " and is still hungry..");
    System.out.println("Needs= " + mNeededAmountOfFood);
    mIsHungry = true;
}

}


回答1:


This method looks like it changes the state of object which calls it, lets say the object is called FoodConsumer.

The eat(Food) changes the state of two variables (mAmountOfEatenFood and mIsHungry).
So, to know if you need to feed that object again the getter method for mIsHungry is needed. It would be good to have getter for mAmountOfEatenFood.
The "obvious" result of eat(Food) is if the object is still hungry.

In test method, you need to have an instance of FoodConsumer. Therefore, later after calling eat(Food) you could call smth like isMHungry() and assert if it's true or false. Additionally you could call getMAmountOfEatenFood() to check if after eating insufficient amount of food it has proper value estimated by food.eatFood(....).

For a little simplification, you could change the eat(Food) to boolean (even for test only) and return true/false just after setting the same value for mIsHungry.

Next, some magic, which we can't see now happens in:

food.eatFood(mNeededAmountOfFood - mAmountOfEatenFood)

If this isn't any kind of library method and you have access to it, then it would be good to have tests convering if value returned by eatFood is good.

I can't say exactly (because of magic in eatFood), but it looks like there is on case uncovered by this method, what if the FoodConsumer over eats (I'm thinking of some conversion rate inside the eatFood which could be over 1).
For example, if neededFood is 100 and eatenFood is 90, then the 10 goes to eatFood which multiplicates that amount by 5. So the eatenFood is incremented with 50 resulting in 140 which is not equal with the amountOfNeededFood.
Simple fix would be to just change your if condition to:

if(mAmountOfEatenFood >= mNeededAmountOfFood){

In the end, lets compare this case witch something like repository.save(User).
Something similar to repo.save(User) is a void method having only a side effects.
Those side effects aren't being explicitly shown when calling save, but then the repo must/should contain of methods which could return some values telling if the inner state of repo was changed.
When testing the repository, to check if save method works correctly, the assertions in test are checking if repository returns the same number of users which were saved and, for example, if the first/second/third user object contains the same values of the objects used when save.



来源:https://stackoverflow.com/questions/59941543/create-junit-test-for-void-method

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!