Страницы

Поиск по вопросам

понедельник, 3 июня 2019 г.

Как реализовать заглушку метода поиска в базе данных для тестового контекста?

Изолирую зависимости от реальной БД при написании модульных тестов в проекте. Интерфейс репозитория имеет следующий вид:
public interface IRepository { T Find(int id) where T: class; }
В реальном контексте метод реализован следующим образом:
public ConcreteDBContext : DBContext, IRepository { //some code public T Find(int id) where T : class { return this.Set.Find(id); } }
Вопрос: как правильно реализовать такой метод в FakeDBContext? И от чего наследовать сам контекст, кроме самого интерфейса IRepository?


Ответ

Если в местах, где вы используете db context, зависимость имеет тип IRepository, то вам достаточно наследовать заглушку от этого интерфейса (для этого зависимости и интерфейсы и нужны :)). Как правило, для каждого теста вам нужна будет своя реализация метода Find. Поэтому правильнее говорить о моках.
Самый правильный способ работать с моками -- использовать мок-фреймворки. Их великое множество: Moq, RhinoMock, NSubstitute и проч. Синтаксис их будет немного отличаться, однако суть работы с моками всегда одна:
Создаем мок-объект. Устанавливаем, что должен возвращать нужный нам метод мок-объекта при вызове с такими-то параметрами. Проверяем, что нужный нам метод был вызван (опционально).
Например, с использованием NSubstite это будет выглядеть так:
var personId = 1;
var repo = Substitute.For(); // для id = 1 возвращаем объект repo.Find(personId).Returns(new Person { Name = "John", LastName = "Doe" }); // для всех остальных id возвращаем null repo.Find(Arg.Is(a => a != 1)).Returns(null);
var someObjectThatUsesRepo = new SomeObjectThatUsesRepo(repo); someObjectThatUsesRepo.SomeMethod();
// проверяем, что метод вызвался ровно один раз repo.Received(1).Find(personId);

Комментариев нет:

Отправить комментарий