2017-06-22 36 views
3

我正在測試我創建的存儲庫模式,並使用Moq包來模擬我的對象。我想測試2個對象的引用,但結果令我驚訝。下面是測試:Assert.AreSame的這種情況應該返回true嗎?

Mock<Repository<Web_Documents>> moqRepo; 
Mock<Repository<Web_Documents>> moqRepo2; 

public void ObjEqGetTest() 
{ 
    //context is DBContext and has been initialized using [TestInitialize] annotation 
    moqRepo = new Mock<Repository<Web_Documents>>(context); 
    moqRepo2 = new Mock<Repository<Web_Documents>>(context); 
    var test = moqRepo.Object.Get(1L); 
    var test2 = moqRepo2.Object.Get(1L); 
    Assert.AreSame(test, test2); 
} 

我的get方法返回:

return entities.SingleOrDefault(predicate) 

使用Expression建設者正在創建predicate(如果需要,我可以添加代碼)。

當我創建了兩個不同的對象時,爲什麼這個Assert返回true?

每次從數據庫中獲取數據(因爲它指向正在使用的模型),Get方法是否返回相同的引用?

感謝您的幫助!

編輯 @CodeCaster表示Mocking回購將在我提出的請求中返回null。但是,當我在我的表Web_Documents中驗證值時,Assertions返回true。讓我來證明這一點:

public void IdExistsGetTest() 
{ 
    moqDoc = new Mock<Repository<Web_Documents>>(context); 
    var testDoc = moqDoc.Object.Get(1L); 
    Assert.AreEqual(testDoc.NomDocument, "Ajouter une catégorie"); 
} 

這個測試是成功的,在Web_Documents,在ID = 1該行已NomDocument = "Ajouter une catégorie"

+0

請閱讀[問]並創建[mcve]。你也不應該依賴DbContext進行單元測試,嘲笑這一點。嘲笑被測試的課程是毫無意義的,你嘲笑依賴關係。 test和test2都是null,這是平等的。 – CodeCaster

+1

我以錯誤的前提爲基礎回答了我的問題,並將其刪除。我所聲稱的只是嘲笑一個界面,而不是嘲笑一個具體的類。我沒有想到Moq在其方法尚未建立的時候會進入具體的課程。儘管如此,你仍然在使用完全錯誤的模擬,會嘗試編輯答案。 – CodeCaster

+0

@CodeCaster我對你說的有什麼問題。我的'Repository'需要一個DBContext參數,所以如果我只嘲笑上下文,當我創建它時如何給我的'Repository'提供一個DBContext參數? –

回答

4

我假設context是實體框架上下文。您可以在兩個存儲庫之間共享它,因此您在不同存儲庫中的兩個查詢將返回相同的實體,因爲實體框架會在上下文內「緩存」實體(在某種意義上)。當它看到你的查詢返回已經附加到上下文的實體時(在這種情況下 - 由第一個查詢返回) - 它將爲第二個實體再次返回相同的實體(如果實體具有相同的主鍵和類型)。

2

Evk已經回答了爲什麼返回值是相同的:DbContext爲相同的主鍵返回相同的實例。

雖然我想說說你的代碼。這裏:

moqRepo = new Mock<Repository<Web_Documents>>(context); 
moqRepo2 = new Mock<Repository<Web_Documents>>(context); 

你在嘲笑你想測試的類。你不應該嘲笑被測試的類,你應該嘲笑它的依賴。

因此嘲笑的DbContext,並注入到這一點你不嘲笑回購:

var contextMock = new Mock<DbContext>(MockBehavior.Strict); 

var repo = new Repository<Web_Documents>(MockBehavior.Strict, contextMock.Object); 
var repo2 = new Repository<Web_Documents>(MockBehavior.Strict, contextMock.Object); 

現在,你必須建立contextMock返回你想要什麼。當按照您的Get()方法調用時調用。

例如參見Mocking EF DbContext with Moq以更多地嘲弄實體框架。

+1

我用這段代碼做了一個測試,並且Get''返回null或者'context'從不被訪問是不正確的。獲取返回實體,因爲它應該訪問上下文,沒有返回空值。這是真的,但OP應該模擬DbContext。 – Evk

+0

@CodeCaster有一件事,我必須修改我的Repository的構造函數,以便它接受'MockBehavior.Strict'?我已經實現了你的建議,但它現在提出MockException說「所有模擬上的調用都必須有相應的設置」,即使我將枚舉添加到Repository構造函數中。 –

+0

@Leo no,該參數指示Moq您想要在模擬類上設置每個調用。如果你不想要(但你應該),那麼從實例化中刪除它。 – CodeCaster

相關問題