ASP.NET MVC 最小起订量 returns 空列表

ASP.NET MVC moq returns empty list

我正在使用最小起订量框架来测试我的 MVC 应用程序。我添加了一个通用存储库和工作单元 class。当我 运行 测试我的控制器时,它失败了,因为模拟 returns 一个空列表(大小 0),即使我添加了两个元素。这是我的测试:

[TestMethod]
        public void Index()
        {
            var repMock = new Mock<IFakultetRepository<Students>>();
            var students = new List<Students>();
            students.Add(new Students() { BI = "10011", Ime = "Pera", Prezime = "Peric", Adresa = "Ulica1", Grad = "Grad1"});
            students.Add(new Students() { BI = "20011", Ime = "Marko", Prezime = "Markovic", Adresa = "Ulica2", Grad = "Grad2" });

            repMock.Setup(x => x.GetEntities()).Returns(students.ToPagedList(1, 5));

            StudentsController controller = new StudentsController(repMock.Object);
            ViewResult result = controller.Index("", "test", "test", 1) as ViewResult;
            var listResult = result.ViewData.Model as PagedList<Students>;
            var list = listResult.ToList();

            Assert.AreEqual(2, list.Count);
}

这是我的通用存储库,它实现了我的通用存储库接口:

public class FakultetRepository<TEntity> : IFakultetRepository<TEntity> where TEntity : class 
    {
        internal FakultetEntities context;
        internal DbSet<TEntity> dbSet;

        public FakultetRepository(FakultetEntities context)
        {
            this.context = context;
            this.dbSet = context.Set<TEntity>();
        }

        public virtual IEnumerable<TEntity> GetEntities()
        {
            return dbSet.ToList();
        }

        public virtual TEntity GetEntityById(object id)
        {
            return dbSet.Find(id);
        }

        public virtual TEntity GetEntityById(string id)
        {
            return dbSet.Find(id);
        }

        public virtual TEntity GetEntityById(object[] id)
        {
            return dbSet.Find(id);
        }

        public virtual void InsertEntity(TEntity entity)
        {
            dbSet.Add(entity);
        }

        public virtual void DeleteEntity(object id)
        {
            TEntity entity = dbSet.Find(id);
            DeleteEntity(entity);
        }

        public virtual void DeleteEntity(TEntity entity)
        {
            if(context.Entry(entity).State == EntityState.Detached)
            {
                dbSet.Attach(entity);
            }
            dbSet.Remove(entity);
        }

        public virtual void UpdateEntity(TEntity entity)
        {
            dbSet.Attach(entity);
            context.Entry(entity).State = EntityState.Modified;
        }
    }

在控制器中,我有一个初始化工作单元并设置其存储库的构造函数:

public StudentsController(IFakultetRepository<Students> studentRepository)
        {
            this.unitOfWork = new UnitOfWork();
            this.unitOfWork.StudentsRepository = studentRepository;
        }

这是我正在测试的控制器方法:

public ActionResult Index(string sortOrder, string currentFilter, string search, int? page)
        {
            ViewBag.CurrentSort = sortOrder;
            ViewBag.NameSortParm = String.IsNullOrEmpty(sortOrder) ? "name_desc" : "";
            ViewBag.BISortParm = sortOrder == "BI" ? "bi_desc" : "BI";
            ViewBag.CitySortParm = sortOrder == "city" ? "city_desc" : "city";

            if (search != null)
            {
                page = 1;
            }
            else
            {
                search = currentFilter;
            }

            ViewBag.CurrentFilter = search;


            var students = from s in unitOfWork.StudentsRepository.GetEntities()
                           select s;

            if (!String.IsNullOrEmpty(search))
            {
                students = students.Where(s => s.Prezime.Contains(search)
                                       || s.Ime.Contains(search)
                                       || s.BI.Contains(search));
            }

            switch (sortOrder)
            {
                case "name_desc":
                    students = students.OrderByDescending(s => s.Prezime);
                    break;
                case "BI":
                    students = students.OrderBy(s => s.BI);
                    break;
                case "bi_desc":
                    students = students.OrderByDescending(s => s.BI);
                    break;
                case "city":
                    students = students.OrderBy(s => s.Grad);
                    break;
                case "city_desc":
                    students = students.OrderByDescending(s => s.Grad);
                    break;
                default:
                    students = students.OrderBy(s => s.Prezime);
                    break;
            }
            int pageSize = 10;
            int pageNumber = (page ?? 1);
            return View("Index", students.ToPagedList(pageNumber, pageSize));
        }

您正在创建两个学生:

students.Add(new Students() 
{ 
    BI = "10011", Ime = "Pera", 
    Prezime = "Peric", Adresa = "Ulica1", 
    Grad = "Grad1"
});

students.Add(new Students() 
{ 
    BI = "20011", Ime = "Marko",
    Prezime = "Markovic", Adresa = "Ulica2", 
    Grad = "Grad2" 
});

您正在调用此控制器方法:

Index(string sortOrder, string currentFilter, string search, int? page)

使用这些值:

result = controller.Index("", "test", "test", 1) as ViewResult;

在控制器方法中,您对调用 GetEntities()

返回的结果应用过滤器
if (!String.IsNullOrEmpty(search))
{
      students = students.Where(s => s.Prezime.Contains(search)
                                  || s.Ime.Contains(search)
                                  || s.BI.Contains(search));   
 }    

正如我们在上面看到的,search 的值是 "test"

因此,假设模拟已被调用并已返回学生,您在单元测试中看到没有返回值的原因是

它们已被过滤器删除。

也可以使用 IList 而不是 List 来解决问题。

请注意,您必须在视图中显示属性。

[Required]
    public IList<ListProductViewModel> Products { get; set; }

 @for (int i = 0; i < Model.Products.Count(); i++)
  {
  <tr id=@Model.Products[i].Id>
    <td>@(rowNo++).</td>
    <td>@Html.DisplayFor(modelItem => Model.Products[i].Name)</td>
    <td>@Html.DisplayFor(modelItem => Model.Products[i].Description)</td>
    <td>@Html.DisplayFor(modelItem => Model.Products[i].Price)</td>
    <td>@Html.DisplayFor(modelItem => Model.Products[i].Tax)</td>
    <td>@Html.DisplayFor(modelItem => Model.Products[i].MeasureUnit)</td>
    <td>@Html.DisplayFor(modelItem => Model.Products[i].Currency)</td>
    <td>@Html.NumberTextBoxFor(modelItem => Model.Products[i].Quantity)</td>
    <td>@Html.CheckBoxBoxFor(modelItem => Model.Products[i].IsSelected)</td>
  </tr>
  }