@Venesuella
BlackJack и ...

Как использование Moq для тестирования репозиториев?

Здравствуйте! Вопрос такой как использовать Moq объекты для тестирования репозиториев? Есть такой репозиторий

public class UserRepository
    {
        private EFDbContext _context;

        public UserRepository(EFDbContext context)
        {
            _context = context;
        }

        public User Find(Guid userId)
        {
            return _context.User.Find(userId);
        }

        public void Add(User user)
        {
            _context.User.Add(user);
            _context.SaveChanges();
        }

        public IReadOnlyCollection<User> GetAll()
        {
            return _context.User.ToList();
        }
    }


прочитай в книге "Искусство автономного тестирования", что Moq применяются чтобы разорвать связь, чтобы тест не зависел от конкретной реализации и не превращался в интеграционный, как я полагаю, мне нужно мокать объект _context, но почему я не могу подключить EF к проекту теста и создавать _context без всяких Moq, т.к приложение использует EF, то и тестирую я репозитории, которые использую EF, т.е получается что Moq объекты в таком случае не нужны??? Разъясните, подскажите как надо, и где я ошибаюсь???
  • Вопрос задан
  • 1025 просмотров
Пригласить эксперта
Ответы на вопрос 2
Milk92
@Milk92
.NET
Вкуривайте.
public UserController :Controller
{ 
   private IUserRepository _userRepository;
public UserController( IUserRepository _userRepository)
{
this._userRepository = _userRepository;
}
   
public ViewResult GetUsers(int count)
{
var users = _userRepository.GetAll().Take(count);

return View(users);
}

}

[TestMethod]
public void GetFiveUsers()
{
//organization
  Mock<IUserRepository> mock = new Mock<IUserRepository>();
  mock.Setup(x=>x.Users).Returns(new List<Users>{
  new User{ Id = Guid.NewGuid(),Name="User#1"},
  new User{ Id = Guid.NewGuid(),Name="User#2"},
  new User{ Id = Guid.NewGuid(),Name="User#3"},
  new User{ Id = Guid.NewGuid(),Name="User#4"}
}); 
//action
UserController controller = new UserController(mock.Object);
IEnumerable<User> usersResult = (IEnumerable<User>)controller.GetUsers(3).Model;// return type action method: ViewResult
//assertion
List<Users> users = usersResult.ToList();
Assert.IsTrue(users.Count()==3);
Assert.AreEqual(users[0].Name, "User#1");
Assert.AreEqual(users[1].Name ,"User#2");
Assert.AreEqual(users[2].Name, "User#3");
}
Ответ написан
@kttotto
пофиг на чем писать
Вы отвечаете на свой вопрос, прежде чем его задать)

При тестировании мокают объекты, чтобы разорвать внешние зависимости.

Необходимо мокать объекты, от которых тестируемый метод зависит, чтобы не тестировать эти самые объекты. Тогда мы будем тестировать только реализацию самого метода. Мы подразумеваем, что эти объекты работают правильно и действую так, как мы того от них ожидаем. Это значит, что мы можем настроить ожидаемое от них поведение.
mock.Setup(x=>x.Users).Returns(new List<Users>(){ ... }

Т.е. мы точно знаем, что при обращении к нашему зависимому объекту через Users нам вернется весь список наших пользователей, причем точно знаем каких. Благодаря абстрагированию от зависимостей, если тестируемый метод провалится, то мы точно будем знать, что виновата реализация метода, а не реализация зависимостей.

В случае тестирования с конкретными зависимыми объектами, мы такого сказать не сможем. Потому что мы точно не можем знать, какие сущности есть в БД, что есть соединение с БД и что сама БД нормально работает.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы