1

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?

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
Jakobbbb
  • 515
  • 1
  • 4
  • 10
  • 1
    Is the purpose of the test to test the repository? If so, mocking out the repository invalidates the whole thing. – user2357112 May 17 '14 at 19:39

1 Answers1

3

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.

Jeroen Vannevel
  • 43,651
  • 22
  • 107
  • 170
  • But then if I test with a existing ID and a non-existing ID. And both tests passes. I guest I still could make some changes to that method so that both tests passes and the method still dont work. The fact that the two tests passes, isn´t it just telling that it works with existing and non-existing id? – Jakobbbb May 17 '14 at 19:56
  • What change will you make that returns an exception for invalid IDs and a `Person` object for valid IDs? Yes, you could willingly introduce side-effects that don't interfere with the flow of the program but that is not something unit tests can guard against. Unit tests are there to verify certain parts of your code do what you expect them to do; they don't make sure that's the *only* thing that's done. – Jeroen Vannevel May 17 '14 at 20:00
  • Yes, it is telling you that works with existing and non-existing IDs. What else do you want a unit test to do? – Jeroen Vannevel May 17 '14 at 20:01
  • I kind of see it now.. But I was thinking that the reason for the tests was that if I make some changes one year from now, and the changes would break the code, the unit test would tell me so.. But not necessarily – Jakobbbb May 17 '14 at 20:05
  • No, they will. If they don't you either have insufficient tests, your tests don't assert against enough post-conditions or you're intentionally going through hoops to circumvent the assertions. If you have good tests and good faith, your tests will guard you against almost all unwanted breaks of code. – Jeroen Vannevel May 17 '14 at 20:10
  • I think its just the mock part I dont quiet get. Because if I mock the repository I have to tell through the setup what should happen when I fx hit the GetByID in the tests. And that way its not the actual method thats being tested. Or am I getting that wrong also? :) – Jakobbbb May 17 '14 at 20:27
  • 1
    To clarify: If you're testing the repository, you shouldn't be mocking it. Is this part of the confusion? – Lilshieste May 17 '14 at 21:12
  • That was the confusion. Thanks to this http://stackoverflow.com/questions/6766478/unit-testing-dbcontext I now understand you dont mock repository :) wait until integration test to test it – Jakobbbb May 17 '14 at 21:29