2017-04-14 16 views
4

私は自分のEF6 DbContextを模倣しようとしており、すべてAddUpdateFindの方法で動作します。しかし、それは不明な理由でRemoveメソッドでは機能しません。Moq&EF6 - モッキングEF6オブジェクトを削除しない方法を削除する

理論的には、取り外した後、Studentsコレクションは1回だけ戻す必要があります。しかし、それはCount - 2を返し続けます。

3 Moq .Verifyチェックを入れて、すべてのメソッドが呼び出され、それらが実際に実行されることを確認します。しかし、それは実際に学生コレクションからアイテムを削除していません。

私が数を確認するAssert.Equal行にコメントした場合、全体のテストは合格しました。

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

方法を削除xUnitのメソッドを削除します。あなたたちはこのRemoveメソッドをモックで私を助けていただけますか?

+0

削除する値は何ですか? – Evk

+0

私はそれをデバッグし、 '1'を返します。 – TTCG

答えて

4

セットアップのほとんどは、あなたが実際にすべてのDbSetモックを削除することができます実際にはDbSet.Remove

に設定を上書きしますDbContext.Studentsを使用して行われた

dbContext 
    .Setup(m => m.Students.Remove(It.IsAny<Student>())) 
    .Callback<Student>((entity) => students.Remove(entity)); 

mockSet 
    .Setup(m => m.Remove(It.IsAny<Student>())) 
    .Callback<Student>((entity) => students.Remove(entity)); 

を交換し、テストは引き続き行われます。

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