#c# #unit-testing #mocking #moq
#c# #модульное тестирование #издевательство #moq
Вопрос:
Новое для Moq и издевательства в целом. Тестирование класса, который имеет универсальный RepositoryFactory и использует несколько своих репозиториев. Должен ли я инициализировать так или есть какой-то лучший способ?
Mock<IRepositoryFactory> factory;
Mock<IRepository<User>> userRepository;
Mock<IRepository<Role>> roleRepository;
Mock<IRepository<Meeting>> meetingRepository;
[TestInitialize()]
public void MyTestInitialize()
{
meetingRepository = new Mock<IRepository<Meeting>>();
//some meeting setup
userRepository = new Mock<IRepository<User>>();
//some user setup
roleRepository = new Mock<IRepository<Role>>();
//some role setup
factory = new Mock<IRepositoryFactory>();
factory.Setup(f => f.CreateRepository<Meeting>()).Returns(meetingRepository.Object);
factory.Setup(f => f.CreateRepository<User>()).Returns(userRepository.Object);
factory.Setup(f => f.CreateRepository<Role>()).Returns(roleRepository.Object);
Обратите внимание, что у меня могло бы быть больше mcuh.
здесь я делаю все это в своем методе инициализации, но, думаю, я должен делать это индивидуально или что-то еще.
Ответ №1:
Я не знаю способа настройки f => f.CreateRepository<T>()
, учитывая, что настройки вашего репозитория могут отличаться для каждого T
. Помимо этого, вы можете использовать функциональные спецификации (см. Это Сообщение в блоге ), что делает вещи немного чище.
Для вашего примера это будет выглядеть так:
var factory = Mock.Of<IRepositoryFactory>(
x =>
x.CreateRepository<Meeting>() == Mock.Of<IRepository<Meeting>>() amp;amp;
x.CreateRepository<Role>() == Mock.Of<IRepository<Role>>() amp;amp;
x.CreateRepository<User>() == Mock.Of<IRepository<User>>()
);
Ответ №2:
Технически я не вижу проблемы с вашим кодом.
Однако немного беспокоит то, что вы даже не начали работать над классом, который хотите протестировать, и у вас уже есть 4 макета, и «может быть гораздо больше». Это звучит как ужасно много настроек.
Кроме того, если я правильно понимаю [TestInitialize], это означает, что для каждого теста в этом классе каждый репозиторий будет настроен одинаково. Это, вероятно, будет мешать указанию тестов с разными условиями.
Возможно, вам следует подумать о том, чтобы избежать [TestInitialize] и настроить нужные вам репозитории в каждом методе тестирования, специфичные для того, что вы хотите утверждать, и постепенно извлекать настройки для каждого репозитория в общие методы, следуя стилю BDD: «Given_User_Of_Type_VIP()» возвращает репозиторий с пользователем типа VIPнастройка.
Комментарии:
1. Ну, причина, по которой я мог бы получить гораздо больше, заключается в том, что это класс обслуживания WCF, который реализует несколько servicecontracts, и в настоящее время я не использую TDD. У сервиса есть только класс RepositoryFactory, но я должен издеваться над репозиториями, которые он может вернуть.