Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

The other day I was reading a little about Unit Testing and I saw some examples where people create a repository interface (i.e. IExampleRepository) and then create the real repository (public class ExampleRepository : IExampleRepository) and a repository to be used for unit testing (FakeExampleRepository : IExampleRepository).

In the IExampleRepository they were implementing the same methods as in the ExampleRepository, however with different Linq queries.

What is exactly the objective here? I thought one part of unit testing your code is make sure that a method works correctly? But when I use two totally different queries, one for 'real' and one in the test, how much sense does the test make?

share|improve this question
add comment

4 Answers

up vote 8 down vote accepted

One of the aims of unit testing is to test just one thing at a time i.e. a single class and method. If the repository itself is not under test then you would normally mock this out in some way so as just to test the logic in your method/class.

That said you do also need to test with a 'real' repository*, but this would normally be done in an integration/system test

*obviously real as in repo set up for test, hopefully not e.g. the production DB.

share|improve this answer
    
So in unit testing I won't be testing the method itself to make sure that it returns the correct values (based on a fake/mocked data set)? –  jao Apr 8 '13 at 9:08
    
yes you will test the method itself but only the code in the method, code in other objects should be covered in other unit tests, the interaction of multiple objects should be covered in integration tests or higher level tests –  jk. Apr 8 '13 at 9:19
1  
Ok, so if I understand correctly, I should use the original repository when unit testing the repositories. I don't need to test them when I'm writing unit tests for the Controllers (in case of Asp.Net MVC) –  jao Apr 8 '13 at 11:27
3  
@Theomax Depends on the context: if you are unit testing a software component which is not your ExampleRepository, then it's best to use a mock. The justification being that you are not unit-testing the repository but something else. –  Andres F. Apr 8 '13 at 17:15
5  
@Theomax To expand AndresF.'s comment: If you are unit testing ExampleRepository, use the real thing. If you are unit testing RepositoryController, then it should only use a FakeExampleRepository that returns pre-specified values. This way, if a bug creeps in to ExampleRepository, only that unit test will fail - RepositoryController's tests will continue to succeed, so you know there isn't a bug there. If the controller used the real repository, they'd both be failing and you wouldn't know if you had 1 bug or 2. –  Izkata Apr 8 '13 at 18:21
show 2 more comments

I agree with the two answers from jk. and Jan Hudec -- they give some really good information. But I thought I'd add a bit.

Your first question ("What exactly is the objective here?") is important. In the case you're describing, the real objective is to test the classes that are utilizing the IExampleRepository interface, not testing the repository implementations. Creating the FakeExampleRepository allows you to test those client classes without worrying about the details of the real repository class.

This is especially true if the object you're trying to set up makes testing difficult (e.g. accesses the file system, calls a webservice, or talks to a database). By using interfaces (and other such techniques), you keep the coupling low. Therefore, class X need only know about the interface and need not know about the implementation details. The goal is all about making sure that class X is doing the right thing.

Mocking (or stubbing, faking... there are nuanced differences) is a powerful tool for unit testing and TDD. But it can be a pain to manually create and maintain these implementations. Therefore, most languages now have mocking libraries to help. Since you're using C#, I'd recommend Moq because it is simple and very powerful. Then you can test against the interface without piling up extra code for the mock implementations.

share|improve this answer
    
the real objective is to test the classes that are utilizing the IExampleRepository interface that's not strictly true. The objective is to test it independently of the IExampleRepository. +1 for recommending a good isolation framework though. –  StuperUser Apr 11 '13 at 16:26
1  
I disagree. It's not independent of the IExampleRepository because the class under test is coupled to that interface. But it is independent of any implementations of the interface. I'll admit that my explanation could probably use a little more finesse though. :) –  Allan Apr 11 '13 at 23:53
add comment

What is exactly the objective here?

Isolation.

The idea of a unit test it to test the smallest possible unit of code. You do this by isolating it from all other production code in the test.

By creating fake classes the only production code is the class under test.

If you create a fake repository properly and the test fails you know that the issue is with the code-under-test. This gives you the benefit of diagnosis for free.

Have a look at isolation frameworks (like Moq as suggested by @Allan) to be able to generate these fakes quickly to setup test conditions and use them to assert against.

share|improve this answer
    
More details on fakes, mocks and stubs: stackoverflow.com/questions/346372/… –  StuperUser Apr 11 '13 at 16:37
add comment

There are three reasons why you might want to provide mock instance to unit test:

  1. You want to limit the scope of the test, so that the test is not affected by bugs in the depndee, possibly because it is not finished yet or is not stable or you don't want bugs in somebody else's affect your tests.
  2. The dependee is complicated to set up. For example data access layer is often mocked out, because the real one requires setting up a test database. You still need to test the real data access layer, but you can limit the costly setup when debugging other things.
  3. To test that the dependent class properly reacts to various kinds of errors, you provide a mock version that returns all sorts of wrong answers. Because many failure modes are rather difficult to reproduce, but should still be tested.
share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.