Учитывая основной интерфейс репозитория:
public interface IPersonRepository
{
void AddPerson(Person person);
List<Person> GetAllPeople();
}
С базовым внедрением:
public class PersonRepository: IPersonRepository
{
public void AddPerson(Person person)
{
ObjectContext.AddObject(person);
}
public List<Person> GetAllPeople()
{
return ObjectSet.AsQueryable().ToList();
}
}
Как может Вы модульный тест это значимым способом? Так как это пересекает границу и физически обновляет и читает из базы данных, это не модульный тест, интеграционный тест.
Или разве неправильно хотеть к модульному тесту это во-первых? У меня должны только быть интеграционные тесты на репозитории?
Я гуглил предмет, и в блогах часто говорится для создания тупика, который реализует IRepository:
public class PersonRepositoryTestStub: IPersonRepository
{
private List<Person> people = new List<Person>();
public void AddPerson(Person person)
{
people.Add(person);
}
public List<Person> GetAllPeople()
{
return people;
}
}
Но это не делает теста единицы PersonRepository, он тестирует реализацию PersonRepositoryTestStub (не очень полезный).
В этом конкретном случае, я думаю, вам не нужно делать модульный тест для вашего класса репозитория, поскольку реализация просто вызывает объект ObjectContext
, так что это будет похоже на тестирование чего-то, чего вы не делали » t build (это не идея). Если у вас нет сложной логики, я рекомендую не тратить время на создание модульного теста для этого класса. То, что вы говорите о PersonRepositoryTestStub, - это поддельная реализация репозитория для тестирования уровня, который находится над вашим DAL.
Я думаю, что этот тип тестирования имеет смысл, когда интерфейс вашего репозитория является универсальным. Например.
public interface IEntity
{
int Id { get; set; }
}
public interface IRepository<TEntity>
where TEntity : IEntity
{
void Add(TEntity entity);
List<TEntity> GetAll();
}
Если у вас есть несколько реализаций этого интерфейса, то также можно написать общий тестовый инструмент, который будет тестировать этот интерфейс, что позволит вам протестировать несколько реализаций репозитория с помощью одного тестового инструмента. Этот подход не делает различий между модульными и интеграционными тестами, потому что он не знает, какова реализация.
Дайте мне знать, если вас интересуют такие вещи, и я могу опубликовать полный пример.
Я бы протестировал уровень бизнес-логики, который зависит от реализации DAL напрямую (имеет сильную ссылку на точную реализацию DAL) или косвенно (абстрагируется от DAL через интерфейсы).
Я не очень люблю тесты, которые используют реализацию-заглушку, просто переносят вызовы базы данных в незавершенную транзакцию (которая откатывает все изменения данных, когда тест завершается, даже если генерируется исключение).
Я столкнулся с той же проблемой. Я написал множество модульных тестов для реализации интерфейса репозитория, который был фальшивым репозиторием. Вскоре после завершения работы я понял, что написал модульный тест для проверки фальшивого хранилища, а фальшивое хранилище написал просто для поддержки модульных тестов. Это казалось большим количеством бесполезного кода.
Я пришел к выводу, что мне не нужны модульные тесты, но реализация фальшивого хранилища хороша тем, что я могу использовать его в качестве хранилища, которое используют мои сервисы (и, следовательно, мои контроллеры), так что модульные тесты против них будут предсказуемы (благодаря предопределенному фальшивому хранилищу).
Поэтому я решил оставить модульные тесты против фальшивого хранилища, поскольку они полезны для тестирования моего фальшивого хранилища, чтобы я мог быть уверен, что на более высоких уровнях моего приложения используются полностью протестированные фальшивки.
Другими словами, поддельный репозиторий и модульные тесты против поддельного репозитория являются "вспомогательным составом" для более высоких уровней приложений и модульных тестов против более высоких уровней приложений.
Надеюсь, это поможет.