Moq & EF6 - 模拟 EF6 Remove 方法不删除 object
Moq & EF6 - Mocking EF6 Remove method not removing an object
我正在尝试模拟我的 EF6 DbContext
,它都适用于 Add
、Update
、Find
方法。但由于未知原因,它不适用于 Remove
方法。
理论上,移除后,Students
collection应该只剩下1个return。但它保持 return 计数 - 2。
我进行了 3 次 Moq.Verify
检查以确保所有方法都被调用并且确实执行了。但它实际上并没有从学生 Collection.
中删除该项目
如果我评论了检查计数的 Assert.Equal
行,则整个测试通过。
删除 XUnit 方法
[Fact]
public void Delete()
{
Mock<DbContexts.MVCWebAppDbContext> dbContext = new Mock<DbContexts.MVCWebAppDbContext>();
IStudentsService studentService = new StudentsService(dbContext.Object);
var students = new List<Student>()
{
new Student() { StudentID = 1, RefNo = "12456343", FirstName = "John", LastName = "Smith", DateOfBirth = DateTime.Now.AddYears(-10), DateCreated = DateTime.Now },
new Student() { StudentID = 2, RefNo = "87984564", FirstName = "Pete", LastName = "Luck", DateOfBirth = DateTime.Now.AddYears(-20), DateCreated = DateTime.Now.AddDays(1) }
};
var mockSet = new Mock<DbSet<Student>>();
mockSet.As<IQueryable<Student>>().Setup(m => m.Provider).Returns(students.AsQueryable().Provider);
mockSet.As<IQueryable<Student>>().Setup(m => m.Expression).Returns(students.AsQueryable().Expression);
mockSet.As<IQueryable<Student>>().Setup(m => m.ElementType).Returns(students.AsQueryable().ElementType);
mockSet.As<IQueryable<Student>>().Setup(m => m.GetEnumerator()).Returns(students.AsQueryable().GetEnumerator());
mockSet.Setup(m => m.Remove(It.IsAny<Student>())).Callback<Student>((entity) => students.Remove(entity));
dbContext.Setup(c => c.Students).Returns(mockSet.Object);
int idToDelete = 1;
dbContext.Setup(s => s.Students.Find(idToDelete)).Returns(students.Single(s => s.StudentID == idToDelete));
// call delete method now
studentService.Delete(idToDelete);
// 1 object deleted, it should return 1
Assert.Equal(1, students.Count()); // <----- Error here
dbContext.Verify(s => s.Students.Find(idToDelete), Times.Once);
dbContext.Verify(s => s.Students.Remove(It.IsAny<Student>()), Times.Once);
dbContext.Verify(s => s.SaveChanges(), Times.Once);
}
StudentService.cs删除方式
MVCWebAppDbContext _context;
public StudentsService(MVCWebAppDbContext context)
{
_context = context;
}
public int Delete(int id)
{
var objToDelete = _context.Students.Find(id);
if (objToDelete != null)
{
_context.Students.Remove(objToDelete);
return _context.SaveChanges();
}
return -1;
}
你们能帮我解决这个 Remove 方法模拟吗?
替换
mockSet
.Setup(m => m.Remove(It.IsAny<Student>()))
.Callback<Student>((entity) => students.Remove(entity));
和
dbContext
.Setup(m => m.Students.Remove(It.IsAny<Student>()))
.Callback<Student>((entity) => students.Remove(entity));
大部分设置是使用 DbContext.Students
完成的,它会覆盖 DbSet.Remove
上的设置
实际上你可以删除所有 DbSet
模拟,测试仍然会通过
[Fact]
public void Delete() {
var dbContext = new Mock<DbContexts.MVCWebAppDbContext>();
IStudentsService studentService = new StudentsService(dbContext.Object);
var students = new List<Student>()
{
new Student() { StudentID = 1, RefNo = "12456343", FirstName = "John", LastName = "Smith", DateOfBirth = DateTime.Now.AddYears(-10), DateCreated = DateTime.Now },
new Student() { StudentID = 2, RefNo = "87984564", FirstName = "Pete", LastName = "Luck", DateOfBirth = DateTime.Now.AddYears(-20), DateCreated = DateTime.Now.AddDays(1) }
};
dbContext
.Setup(m => m.Students.Remove(It.IsAny<Student>()))
.Callback<Student>((entity) => students.Remove(entity));
int idToDelete = 1;
dbContext
.Setup(s => s.Students.Find(idToDelete))
.Returns(students.Single(s => s.StudentID == idToDelete));
// call delete method now
studentService.Delete(idToDelete);
// 1 object deleted, it should return 1
Assert.AreEqual(1, students.Count());
dbContext.Verify(s => s.Students.Find(idToDelete), Times.Once);
dbContext.Verify(s => s.Students.Remove(It.IsAny<Student>()), Times.Once);
dbContext.Verify(s => s.SaveChanges(), Times.Once);
}
我正在尝试模拟我的 EF6 DbContext
,它都适用于 Add
、Update
、Find
方法。但由于未知原因,它不适用于 Remove
方法。
理论上,移除后,Students
collection应该只剩下1个return。但它保持 return 计数 - 2。
我进行了 3 次 Moq.Verify
检查以确保所有方法都被调用并且确实执行了。但它实际上并没有从学生 Collection.
如果我评论了检查计数的 Assert.Equal
行,则整个测试通过。
删除 XUnit 方法
[Fact]
public void Delete()
{
Mock<DbContexts.MVCWebAppDbContext> dbContext = new Mock<DbContexts.MVCWebAppDbContext>();
IStudentsService studentService = new StudentsService(dbContext.Object);
var students = new List<Student>()
{
new Student() { StudentID = 1, RefNo = "12456343", FirstName = "John", LastName = "Smith", DateOfBirth = DateTime.Now.AddYears(-10), DateCreated = DateTime.Now },
new Student() { StudentID = 2, RefNo = "87984564", FirstName = "Pete", LastName = "Luck", DateOfBirth = DateTime.Now.AddYears(-20), DateCreated = DateTime.Now.AddDays(1) }
};
var mockSet = new Mock<DbSet<Student>>();
mockSet.As<IQueryable<Student>>().Setup(m => m.Provider).Returns(students.AsQueryable().Provider);
mockSet.As<IQueryable<Student>>().Setup(m => m.Expression).Returns(students.AsQueryable().Expression);
mockSet.As<IQueryable<Student>>().Setup(m => m.ElementType).Returns(students.AsQueryable().ElementType);
mockSet.As<IQueryable<Student>>().Setup(m => m.GetEnumerator()).Returns(students.AsQueryable().GetEnumerator());
mockSet.Setup(m => m.Remove(It.IsAny<Student>())).Callback<Student>((entity) => students.Remove(entity));
dbContext.Setup(c => c.Students).Returns(mockSet.Object);
int idToDelete = 1;
dbContext.Setup(s => s.Students.Find(idToDelete)).Returns(students.Single(s => s.StudentID == idToDelete));
// call delete method now
studentService.Delete(idToDelete);
// 1 object deleted, it should return 1
Assert.Equal(1, students.Count()); // <----- Error here
dbContext.Verify(s => s.Students.Find(idToDelete), Times.Once);
dbContext.Verify(s => s.Students.Remove(It.IsAny<Student>()), Times.Once);
dbContext.Verify(s => s.SaveChanges(), Times.Once);
}
StudentService.cs删除方式
MVCWebAppDbContext _context;
public StudentsService(MVCWebAppDbContext context)
{
_context = context;
}
public int Delete(int id)
{
var objToDelete = _context.Students.Find(id);
if (objToDelete != null)
{
_context.Students.Remove(objToDelete);
return _context.SaveChanges();
}
return -1;
}
你们能帮我解决这个 Remove 方法模拟吗?
替换
mockSet
.Setup(m => m.Remove(It.IsAny<Student>()))
.Callback<Student>((entity) => students.Remove(entity));
和
dbContext
.Setup(m => m.Students.Remove(It.IsAny<Student>()))
.Callback<Student>((entity) => students.Remove(entity));
大部分设置是使用 DbContext.Students
完成的,它会覆盖 DbSet.Remove
实际上你可以删除所有 DbSet
模拟,测试仍然会通过
[Fact]
public void Delete() {
var dbContext = new Mock<DbContexts.MVCWebAppDbContext>();
IStudentsService studentService = new StudentsService(dbContext.Object);
var students = new List<Student>()
{
new Student() { StudentID = 1, RefNo = "12456343", FirstName = "John", LastName = "Smith", DateOfBirth = DateTime.Now.AddYears(-10), DateCreated = DateTime.Now },
new Student() { StudentID = 2, RefNo = "87984564", FirstName = "Pete", LastName = "Luck", DateOfBirth = DateTime.Now.AddYears(-20), DateCreated = DateTime.Now.AddDays(1) }
};
dbContext
.Setup(m => m.Students.Remove(It.IsAny<Student>()))
.Callback<Student>((entity) => students.Remove(entity));
int idToDelete = 1;
dbContext
.Setup(s => s.Students.Find(idToDelete))
.Returns(students.Single(s => s.StudentID == idToDelete));
// call delete method now
studentService.Delete(idToDelete);
// 1 object deleted, it should return 1
Assert.AreEqual(1, students.Count());
dbContext.Verify(s => s.Students.Find(idToDelete), Times.Once);
dbContext.Verify(s => s.Students.Remove(It.IsAny<Student>()), Times.Once);
dbContext.Verify(s => s.SaveChanges(), Times.Once);
}