После прочтения есть много примеров, я вижу, что я полагаю, что у есть интерфейс. Где именно это нужно? В папке контроллера , тестовом проекте?
Существует не правило, где хранить интерфейсы, но обычно вы держите их близко к коду, который их использует. Обычно у меня есть классы домена и службы в отдельной сборке с интерфейсами репозитория, определенными там. Затем я ссылаюсь на эту сборку сборкой данных, которая имеет реализации интерфейсов репозитория. И последний шаг - я ссылаюсь на обе сборки из веб-приложения.
Если я тестирую метод в моем контроллере и имеет несколько вызовов децибела, как бы я MOq что
Помните, что хорошие модульные тесты должны быть быстро, Isolated, Повторяется, Само- Проверка и своевременность (FIRST). Наличие вызовов базы данных в контроллере не позволяет быстро запускать тесты (вызовы базы данных очень медленные по сравнению с кодом в памяти), чтобы изолировать тестовый контроллер и делать тесты всегда повторяемыми. Также ваш контроллер просто выполняет многие действия (т. Е. Нарушает принцип SRP) - он получает пользовательский ввод, выполняет запросы к базе данных и подготавливает модель для просмотра.
Итак, для того, чтобы отделить обязанности и сделать ваш контроллер проверяемым, вы должны связанными экстракта доступа к данным кода для отдельного класса (как правило, такие классы называются хранилищ). И создать абстракцию, которая будет указывать API между контроллером и хранилища:
public interface IYourRepository
{
IEnumerable<pType> FetchPData();
IEnumerable<sType> FetchSData();
}
Затем сделайте ваш контроллер зависит от этой абстракции (обратная зависимость), и впрыснуть хранилище на контроллер (можно использовать Ninject, Unity или другие рамки инъекции зависимостей) :
IYourRepository _repository;
public YourController(IYourRepository repository)
{
_repository = repository;
}
public ActionResult Index()
{
var model = new myModel();
foreach (var p in _repository.FetchPData())
// do stuff
foreach (var s in _repository.FetchSData())
// do stuff
return View("Index", model);
}
Это позволит издеваться хранилище легко и обеспечить высмеивал объект управления:
var repositoryMock = new Mock<IYourRepository>();
repositoryMock.Setup(r => r.FetchPData()).Returns(pList);
repositoryMock.Setup(r => r.FetchSData()).Returns(sList);
var controller = new YourController(repositoryMock.Object);
var result = controller.Index();
// Assertions
ОК Я понимаю, знаю. Поэтому в будущем я должен написать свой метод так, чтобы его также можно было легко высмеивать. –
Я должен упомянуть, что 'FetchPData' и' FetchSData' являются статическим методом actaully, вызываемым из другого класса. –
@JackThor, даже после того, как вы редактировали вопрос, ответ тот же - сделайте их нестатичными и добавьте еще один экземпляр класса в контроллер. –