When i debugging the controller index method it returns an empty model where I do mistake? I am using Moq by Daniel Cazzulino and xUnit
Following is my controller code:
TeacherController:
public class TeacherController : Controller
{
private IClassScheduleUnitOfWork _classScheduleUnitOfWork { get; set; }
public TeacherController(IClassScheduleUnitOfWork classScheduleUnitOfWork)
{
_classScheduleUnitOfWork = classScheduleUnitOfWork;
}
public ViewResult Index()
{
var options = new QueryOptions<Teacher> {
OrderBy = t => t.LastName
};
IEnumerable<Teacher> list = _classScheduleUnitOfWork.teachers.List(options);
return View("Index", list);
}
}
Here is my Unit test controller code:
public class TeacherControllerTests
{
private readonly Mock<IClassScheduleUnitOfWork> _mock;
public TeacherControllerTests()
{
_mock = new Mock<IClassScheduleUnitOfWork>();
}
[Fact]
public void IndexActionMethod_ReturnsAViewResult()
{
var options = new QueryOptions<Teacher>
{
OrderBy = t => t.LastName
};
IEnumerable<Teacher> teachersList = GetAllTeachers();
_mock.Setup(x =>x.teachers.List(options))
.Returns(teachersList);
var controller = new TeacherController(_mock.Object);
//act
var result = controller.Index();
var actualData = (IEnumerable<Teacher>?)result?.ViewData.Model;
Assert.Equal(5, actualData?.Count());
}
private IEnumerable<Teacher> GetAllTeachers()
{
IEnumerable<Teacher> teachers = new List<Teacher>()
{
new Teacher { TeacherId = 1, FirstName = "Anne", LastName = "Sullivan" },
new Teacher { TeacherId = 2, FirstName = "Maria", LastName = "Montessori" },
new Teacher { TeacherId = 3, FirstName = "Martin Luther", LastName = "King" },
new Teacher { TeacherId = 4, FirstName = "", LastName = "Aristotle" },
new Teacher { TeacherId = 5, FirstName = "Jaime", LastName = "Escalante" }
};
teachers = teachers.OrderBy(t => t.LastName).ToList();
return teachers;
}
}
Here is the definition of IClassScheduleUnitOfWork
public interface IClassScheduleUnitOfWork
{
public IRepository<Teacher> teachers { get; set; }
public IRepository<Class> classes { get; set; }
public IRepository<Day> days { get; set; }
public void Save();
}
Here is the IRepository code:
public interface IRepository<T> where T : class
{
IEnumerable<T> List(QueryOptions<T> options);
T? Get(int id);
T? Get(QueryOptions<T> queryOptions);
void Insert(T entity);
void Update(T entity);
void Delete(T entity);
void Save();
}
The problem is that the QueryOptions<Teacher>
object (options
) in the test is not the same object as the QueryOptions<Teacher>
object (options
) in the System Under Test (SUT).
Thus, the expression x =>x.teachers.List(options)
will never be matched.
You can loosen the Setup
a bit to make the test pass:
_mock.Setup(x => x.teachers.List(It.IsAny<QueryOptions<Teacher>>()))
.Returns(teachersList);
If it were me, though, I'd re-evaluate my options, since this is a test-unfriendly design for that very reason.