Jakobbbb
Jakobbbb

Reputation: 545

Can I rely on a (single) unit test to verify both valid and invalid state of my unit under test?

Using this article I now want to test some repositories.

I use Moq to make a mock of the repository, and setup the GetAll, and GetByID methods. The unit test passes, and everything is good.

But when I comment out the code in GetAll() in the repository class and put in a NotImplementedException() the unit test still passes.

Would that mean that if I make some changes to the code, the new implementation of GetAll() could break my code while still letting my tests pass?

Upvotes: 1

Views: 376

Answers (1)

Jeroen Vannevel
Jeroen Vannevel

Reputation: 44449

It means your unit tests are incomplete: you have to test both valid and invalid situations. As you indicate yourself: you want to know when something works but you also want to know when it fails.

Consider the following two examples:

@Test(expected = PersonNotFoundException.class)
public void GetPerson_WithNonExistingId_ShouldThrowPersonNotFoundException(){
    Person person = new PersonRepository().getPersonById(-1);
}

@Test
public void GetPerson_WithExistingId_ShouldReturnPerson(){
    Person person = new PersonRepository().getPersonById(5);
    Assert.AssertNotNull(person);
}

Now you have two tests that will verify the method's behaviour both when it is supposed to work and when it shouldn't. If you now suddenly change the implementation of PersonRepository.getPersonById(int) to always throw PersonNotFoundException, your first test will still succeed but the other one won't.

It is advised to validate the spectrum of distinct input paths. This often includes

  • Passing null values
  • Passing out-of-bound values
  • Passing negative values
  • Passing non-existing values

etc

I realized too late that Moq is C#, not Java. This idea is language-agnostic though and the code speaks for itself.

Upvotes: 3

Related Questions