使用 xUnit 和 Mock 进行单元测试时,Controller ViewResult 返回空模型集合

问题描述 投票:0回答:1

当我调试控制器索引方法时,它返回一个空模型,我在哪里犯了错误? 我正在使用 Daniel Cazzulino 的 Moq 和 xUnit

以下是我的控制器代码:

教师控制器:

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

这是我的单元测试控制器代码:

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

这是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();

 }

这是 IRepository 代码:

 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();
 }
c# unit-testing asp.net-core asp.net-core-mvc moq
1个回答
0
投票

问题是测试中

中的
QueryOptions<Teacher>
对象 (
options) 与被测系统 (SUT) 中的QueryOptions<Teacher>
对象 (
options
) 不是同一个对象

因此,表达式

x =>x.teachers.List(options)
将永远不会被匹配。

您可以稍微松开

Setup
以使测试通过:

_mock.Setup(x => x.teachers.List(It.IsAny<QueryOptions<Teacher>>()))
    .Returns(teachersList);

但是,如果是我,我会重新评估我的选择,因为正是出于这个原因,这是一个测试不友好的设计。

© www.soinside.com 2019 - 2024. All rights reserved.