我想弄明白單元測試中的嘲弄,並將單元測試過程集成到我的項目中。所以我一直在通過幾個教程,並重構我的代碼來支持嘲笑,無論如何,我無法通過測試,因爲我試圖測試的數據庫方法是使用事務,但創建事務時,我得到獲取過去的實體框架BeginTransaction
底層提供程序在打開時失敗。
沒有交易一切正常。
我目前擁有的代碼是:被測
[TestMethod]
public void Test1()
{
var mockSet = GetDbMock();
var mockContext = new Mock<DataContext>();
mockContext.Setup(m => m.Repository).Returns(mockSet.Object);
var service = new MyService(mockContext.Object);
service.SaveRepository(GetRepositoryData().First());
mockSet.Verify(m => m.Remove(It.IsAny<Repository>()), Times.Once());
mockSet.Verify(m => m.Add(It.IsAny<Repository>()), Times.Once());
mockContext.Verify(m => m.SaveChanges(), Times.Once());
}
// gets the DbSet mock with one existing item
private Mock<DbSet<Repository>> GetDbMock()
{
var data = GetRepositoryData();
var mockSet = new Mock<DbSet<Repository>>();
mockSet.As<IQueryable<Repository>>().Setup(m => m.Provider).Returns(data.Provider);
// skipped for brevity
return mockSet;
}
代碼:
private readonly DataContext _context;
public MyService(DataContext ctx)
{
_context = ctx;
}
public void SaveRepositories(Repository repo)
{
using (_context)
{
// Here the transaction creation fails
using (var transaction = _context.Database.BeginTransaction())
{
DeleteExistingEntries(repo.Id);
AddRepositories(repo);
_context.SaveChanges();
transaction.Commit();
}
}
}
我試圖嘲弄交易部分,以及:
var mockTransaction = new Mock<DbContextTransaction>();
mockContext.Setup(x => x.Database.BeginTransaction()).Returns(mockTransaction.Object);
但這不起作用,失敗:
無效設置在非虛擬(在VB重寫)成員:CONN => conn.Database.BeginTransaction()
任何想法如何解決此問題?
這種設計模式很有意義,我會努力去理解它。儘管我仍然無法實現它,因爲我不能嘲笑'DbContextTransaction',因爲它只有內部構造函數,這似乎是'Moq'的一個問題。無論如何,它認爲測試執行並不依賴於它的工作,如果我不經過調試就運行測試,它們會通過,除非我明確檢查是否有任何異常被拋出。這很好。感謝洞察力,除非有更好的發現,否則我會接受。 (y) –
你可以在那裏得到同樣的技巧 - 創建一個由'DbContextTransactionAdapter'實現的'IDbContextTransaction'接口,它包裝一個實際的'DbContextTransaction' - 並且在你的測試中模擬'IDbContextTransaction'。這有點麻煩,但這個技巧通常會使使用庫代碼的代碼更容易測試,並且與庫更緊密地耦合。 –
最近有一件事讓我驚訝,當我做了Mock.Of是模擬的數據庫屬性創建一個具體的數據庫對象使用app.config中的連接信息。因此,任何Database.ExecuteSql都可能會針對該數據庫運行。還從BeginTransaction返回了具體的事務。這是怎麼回事,一個模擬回報真實的東西? –