I am new to unit testing and was trying to write unit tests for controllers' action methods using Moq Library and Xunit framework. I created a list of departments as mock data and tried testing it by passing in Returns() method with the Setup() method of the Moq. But it shows error
"Cannot convert type 'System.Collections.Generic.List<DotNetMvcDemo.Models.Department>' to 'System.Web.Mvc.ActionResult' via a reference conversion, boxing conversion, unboxing conversion, wrapping conversion, or null type conversion".
public ActionResult Index()
{
//var departments = db.Departments.Include(d => d.CreatorUser).Include(d => d.UpdaterUser);
var departments = new List<Department>();
using (var db = new ApplicationDbContext())
{
departments = db.Departments.ToList();
}
var departmentsViewList = new List<DepartmentViewModel>();
foreach (var department in departments)
{
var departmentView = new DepartmentViewModel();
departmentView.Id = department.Id;
departmentView.Name = department.Name;
departmentView.Description = department.Description;
departmentsViewList.Add(departmentView);
}
return View(departmentsViewList);
}
public Mock<DepartmentsController> mock = new Mock<DepartmentsController>();
private readonly DepartmentsController _controller;
public DepartmentControllerTest()
{
_controller = new DepartmentsController();
}
private static List<Department> GetTestDepartments()
{
var mockDepartments = new List<Department>
{
new Department()
{
Id = 1,
Name = "test one",
Description = "test desc"
},
new Department()
{
Id = 2,
Name = "test two",
Description = "test desc"
},
new Department()
{
Id = 3,
Name = "test three",
Description = "test desc"
}
};
return mockDepartments;
}
[Fact]
public void Can_Get_Department()
{
//Arrange
mock.Setup(m => m.Index()).Returns(GetTestDepartments() as ActionResult);
//Act
//Assertion
}
I looked for solution how to write unit test with Moq and xunit in ASP.NET MVC application. But I could not relate to my problem as most of the tutorials used Interface/ Repository Pattern to do unit testing and I have only controllers to work with. Can I get a suggestion or a guideline how can I properly write unit test for CRUD operations?
CodePudding user response:
First, you actually need to create interfaces and service layer for testing. If you can't write simple test, then it something is wrong in code and needs to be refactored.
Second, controller should not contain any logic, and so there is no need to unit test controllers. All this code should be in a service somewhere.
And finally, for this case, you need to setup mock of db.Departments.ToList()
to return value of GetTestDepartments(), not Index() action, then you assert result of Index() to whatever you want...
In addition, you don't "unit test" CRUD operations, you integration, or smoke test them, and for that, you should use in-memory database...