Reputation: 33
I need to mock simple class :
namespace Infrastructure.Repositores
{
public class StudentRepository : IStudentRepository
{
private readonly GradeBookDBContext _dbContext;
public StudentRepository(GradeBookDBContext dbContext)
{
_dbContext = dbContext;
}
public IEnumerable<Student> GetAllStudents()
{
var students = _dbContext.Students;
return students;
}
I try to do something like this but its not work... I'm beginner in mock testing, can someone explain me why it is not work?
[Fact]
public void Test2()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(SampleStudents);
StudentRepository ss = new StudentRepository();
var expected = SampleStudents();
var actual = ss.GetAllStudents();
Assert.Equal(expected, actual);
}
private List<Student> SampleStudents()
{// list of sample objects}
How to mock this class keeping good practices?
Upvotes: 0
Views: 69
Reputation: 2304
.Returns(SampleStudents)
must be .Returns(SampleStudents())
, although Assert.Equal(expected, actual) would still give throw exceptions unless Student
is a struct
Then there is this line StudentRepository ss = new StudentRepository();
. It doesn't make sense to create a mock and then use the original class
So you should do somehting like this
[Fact]
public void Test1()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
var expected = Sample();
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(expected);
var actual = studentRepositoryMock.Object.GetAllStudents();
Assert.Equal(expected, actual);
}
Obviously that doesn't make sense, because you don't test anything useful this way. If you want to test StudentRepository just create StudentRepository and test it. Creating mock for IStudentRepository makes sense when you have a class that uses it, for instanse
public class StudentService
{
private IStudentRepository _repo;
public StudentService(IStudentRepository repo)
{
_repo = repo;
}
public List<Student> GetIgors()
{
return _repo.GetAllStudents().Where(x => x.Name == "Igor").ToList();
}
}
Then your test would look like this
[Fact]
public void Test1()
{
Mock<IStudentRepository> studentRepositoryMock =
new Mock<IStudentRepository>();
var expected = new List<Student>()
{
new Student() {Name = "Igor"},
new Student() {Name = "NotIgor"}
};
studentRepositoryMock.Setup(x => x.GetAllStudents())
.Returns(expected);
var sm = new StudentService(studentRepositoryMock.Object);
var actual = sm.GetIgors();
Assert.True(actual.All(x => x.Name == "Igor"));
}
Disclaimer: I don't actually suggest you to write db queries this way, filter elements before converting the collection to IEnumerable
, it's just an example of using moq library. If you want to test repository check this article , don't use the moq library for that.
Upvotes: 2