[英]How to test Add method with Moq in C#
我嘗試為存儲庫類中的 Add 方法編寫單元測試。 我正在使用 EF6 和 Moq。 我的測試方法看起來:
public static Mock<DbSet<T>> CreateDbSetMock<T>(IEnumerable<T> elements) where T : class
{
var elementsAsQueryable = elements.AsQueryable();
var dbSetMock = new Mock<DbSet<T>>();
dbSetMock.As<IQueryable<T>>().Setup(m => m.Provider).Returns(elementsAsQueryable.Provider);
dbSetMock.As<IQueryable<T>>().Setup(m => m.Expression).Returns(elementsAsQueryable.Expression);
dbSetMock.As<IQueryable<T>>().Setup(m => m.ElementType).Returns(elementsAsQueryable.ElementType);
dbSetMock.As<IQueryable<T>>().Setup(m => m.GetEnumerator()).Returns(elementsAsQueryable.GetEnumerator());
return dbSetMock;
}
[Test()]
public void AddTest()
{
// Arrange
Mock<DbSet<Tytul>> titlesMock = CreateDbSetMock(new List<Tytul>());
Mock<OzinDbContext> titlesContextMock = new Mock<OzinDbContext>();
titlesContextMock.Setup(x => x.Tytuly).Returns(titlesMock.Object);
titlesMock.Setup(x => x.Add(It.IsAny<Tytul>())).Returns((Tytul t) => t);
IRepository<Tytul> tytulRepository = TytulRepository(titlesContextMock.Object);
Tytul tytul = new Tytul
{
Identyfikator = "ABC"
};
// Act
tytulRepository.Add(tytul);
// in Add method:
//dbContext.Tytuly.Add(entity);
//dbContext.SaveChanges();
Tytul tytulInDb = tytulRepository.GetDetail(t => t.Identyfikator == "ABC");
// in GetDetail method:
//return dbContext.Tytuly.FirstOrDefault(predicate);
// Assert
Assert.AreEqual(tytulInDb.Identyfikator, tytul.Identyfikator);
}
我的問題是 GetDetail 方法返回 null,但我期望 tytulInDb 對象。 怎么了? 如何正確地編寫 thist 測試?
將 DbSet 的假數據源提取到局部變量中,以便稍后在測試設置中進行交互。 向Add
設置添加Callback
以將傳遞的參數添加到數據源,以便在調用時模擬可以處理實際數據。
// Arrange
var data = new List<Tytul>(); //<<< local variable
Mock<DbSet<Tytul>> titlesMock = CreateDbSetMock(data);
var titlesContextMock = new Mock<OzinDbContext>();
titlesContextMock.Setup(x => x.Tytuly).Returns(titlesMock.Object);
titlesMock
.Setup(x => x.Add(It.IsAny<Tytul>()))
.Returns((Tytul t) => t)
.Callback((Tytul t) => data.Add(t)); //<<< for when mocked Add is called.
IRepository<Tytul> tytulRepository = TytulRepository(titlesContextMock.Object);
//...Code removed for brevity
此外,在設置 DbSet Mock 時,請使用Returns
的委托以允許多個枚舉,因為僅返回值將僅允許前向枚舉器的一次傳遞。
dbSetMock.As<IQueryable<T>>()
.Setup(m => m.GetEnumerator())
.Returns(() => elementsAsQueryable.GetEnumerator()); //<<< note delegate
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.