c# – How do I stub a database lookup method for a test context?

Question:

I isolate dependencies from a real database when writing unit tests in a project. The repository interface looks like this:

public interface IRepository
{
   T Find<T>(int id) where T: class;
}

In a real context, the method is implemented as follows:

public ConcreteDBContext : DBContext, IRepository
{
//some code
   public T Find<T>(int id) where T : class
   {
      return this.Set<T>.Find(id);
   }
}

The question is: how to properly implement such a method in FakeDBContext? And from what to inherit the context itself, except for the IRepository interface itself?

Answer:

If, in the places where you use the db context, the dependency has the IRepository type, then you just need to inherit the stub from this interface (for this, dependencies and interfaces are needed :)). Typically, you will need a different implementation of the Find<T> method for each test case. Therefore, it is more correct to talk about mocks.

The most correct way to work with mocks is to use a mock framework. There are a lot of them: Moq, RhinoMock, NSubstitute, etc. Their syntax will be slightly different, but the essence of working with mocks is always the same:

  1. Create a mock object.
  2. We establish that the mock object method we need should return when called with such and such parameters.
  3. We check that the method we need has been called (optional).

For example, using NSubstite it would look like this:

var personId = 1;

var repo = Substitute.For<IRepository>();
// для id = 1 возвращаем объект
repo.Find<Person>(personId).Returns(new Person { Name = "John", LastName = "Doe" });
// для всех остальных id возвращаем null
repo.Find<Person>(Arg.Is(a => a != 1)).Returns(null);

var someObjectThatUsesRepo = new SomeObjectThatUsesRepo(repo);
someObjectThatUsesRepo.SomeMethod();

// проверяем, что метод вызвался ровно один раз
repo.Received(1).Find<Person>(personId);
Scroll to Top