D
D
Dmitry2016-08-22 20:45:06
ASP.NET
Dmitry, 2016-08-22 20:45:06

How to use Moq to test repositories?

Hello! The question is how to use Moq objects to test repositories? There is such a repository

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();
        }
    }

read in the book The Art of Standalone Testing that Moqs are used to decouple so that the test doesn't depend on a specific implementation and turn into an integration, I guess I need to mock the _context object, but why can't I connect EF to the test project and create _context without any Moq, since the application uses EF, then I test the repositories that I use EF, that is, it turns out that Moq objects are not needed in this case ??? Explain, prompt as it is necessary, and where I am mistaken???

Answer the question

In order to leave comments, you need to log in

2 answer(s)
M
Michael, 2016-08-26
@Milk92

Smoke it.

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");
}

E
eRKa, 2016-09-01
@kttotto

You answer your own question before you ask it)
When testing, objects are mocked to break external dependencies.
It is necessary to mock the objects on which the method under test depends, so as not to test these same objects. Then we will only test the implementation of the method itself. We assume that these objects work correctly and act as we expect them to. This means that we can customize the behavior we expect from them.
Those. we know for sure that when accessing our dependent object through Users, the entire list of our users will be returned to us, and we know exactly which ones. With dependency abstraction, if the method under test fails, we know for sure that the implementation of the method is at fault, not the implementation of the dependencies.
In the case of testing with specific dependent objects, we cannot say this. Because we cannot know for sure what entities are in the database, that there is a connection to the database, and that the database itself is working fine.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question