Question

I need to learn Mockito for my current project and am struggling mightely. I might add that i've also never been taught anything on unit testing either (and very little in java for that mater, haha) so I seem to have to learn multiple things at once. I have spent awhile looking at a number of resources on Mockito but could still use some help. Below I have created a small example that I'm hoping someone can answer for me on creating a JUNIT for it in Mockito.

public class Animal{

    public numberOfTeeth(AnimalType animal){
          if animalAlive(){
               Teeth tooth= animal.getNumberOfTeeth();
                if(tooth== null) {     
                    throw new ValidationException("Invalid Tooth");        
                 }
          }
    }

Please excuse the syntax errors, this is a quick made up example for learning.

So lets say animalAlive() is a private method in the Animal Class and getNumberOfTeeth() is a public method in some other class. I assume one junit test one might make would be to test if the exception is thrown when it should? What would the best way to do this be?

I would assume it involves mocking AnimalType and creating stubs(?) to control the two method calls inside the numberOfTeeth method? Does the Private method inside the Animal class throw a wrench in anything?

Was it helpful?

Solution

To be entirely thorough in your testing of this method, I'd say you want test cases for the following three scenarios.

  • the exception is thrown when the animal is alive and the number of teeth is null,
  • no exception when the animal is alive and the number of teeth is not null,
  • no exception when the animal is dead.

So you'll need the following.

  • an Animal object to test,
  • a mocked AnimalType,
  • a valid Tooth object, which may or may not be a mock,
  • a JUnit ExpectedException rule - there are other ways of testing that exceptions are thrown, but this is the most versatile, so I recommend learning to use it now, and using it in all of your tests that involve exceptions, even if it seems overkill.

In your AnimalTest class, you'll have three test methods, one for each of the scenarios that you're going to test.

numberOfTeethFailsForLiveAnimalWithInvalidTeeth

  1. Use the exception rule to "expect" a ValidationException.
  2. Call numberOfTeeth on a live animal, with your mock AnimalType. Since you haven't stubbed getNumberOfTeeth(), it will return null, so the exception should be thrown.

numberOfTeethSucceedsForLiveAnimalWithValidTeeth

  1. Stub your mock AnimalType to return a valid Tooth from getNumberOfTeeth().
  2. Call numberOfTeeth on a live animal, with your mock AnimalType.

There is no need to verify anything - the fact that this method completes means the exception is not thrown.

numberOfTeethSucceedsForDeadAnimal

  1. Call whatever method you need to call, to make your animal "not alive".
  2. Call numberOfTeeth on a live animal, with your mock AnimalType.

Again, there is no need to verify anything - the fact that this method completes means the exception is not thrown.

There are a few small things you can do to improve your code.

  • Don't call your AnimalType parameter animal, when you have a type called Animal - it's just too confusing.
  • Use a different name for the getNumberOfTeeth() method - it doesn't return a number, it returns a Tooth, so this name is also confusing.
  • Use a constant for your error message. This way, in the test method that uses the exception rule, you can verify that the text of the error is correct, but actually use the constant when you do this. Not duplicating the text reduces the danger of changing the message in the application class but not in the test class.
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top