2009-04-27 70 views
3

我們使用C#和Linq2SQL和MS SQL Server數據庫。 我們有一個mockdatacontext來進行一些單元測試。 測試時,根據是否使用「真實」或「模擬」數據庫,我們發現了兩種不同的行爲。「模擬」數據庫與「真實」數據庫行爲之間的差異

方案1:真正的數據庫

有5個記錄中的數據庫:

db = realDatabase 
db.InsertOnSubmit(new record) 

var count1 = db.getTable.Count() 

db.SubmitChanges() 

var count2 = db.getTable.Count() 

COUNT1 = COUNT2 =

方案2:模擬數據庫

有5條記錄在數據庫中:

db= mockDatabase 

db.InsertOnSubmit(new record) 

var count1 = db.getTable.Count() 

db.SubmitChanges() 

var count2 = db.getTable.Count() 

COUNT1 = COUNT2 =

* 「模擬」 數據庫已經知道的SubmitChanges之前的新紀錄( )被調用,所以它被包括在計數中。爲了測試,我們需要兩種行爲是相同的。

有沒有其他人遇到過這個問題,你能提出一個解決方案嗎?

+0

你的模擬數據庫是如何實現的? – 2009-04-27 20:55:52

回答

0

我猜你的模擬數據庫(在內存?? ??)不是事務性的,並且InsertOnSubmit方法實際上是插入記錄。

7

IMO,這是一個常見的錯誤,一個試圖在測試中模擬。 模擬不是模擬器。它不應該實現類似於原始的邏輯,它應該返回硬編碼的結果。

如果模擬行爲很複雜,那麼最終會測試您的模擬而不是您的業務代碼。

我使用RhinoMocks,它應該是這樣的:

// arrange 
IList<Record> testdata = new List<Record>() {a, b, c}; 
db = MockRepository.GenerateMock<IDatabase>(); 
db.Stub(x => db.getTable).Return(testdata); 

// act: call your unit under test 

// assert 
db.AssertWasCalled(x => x.InsertOnSubmit(Arg<Record>.Is.Anything)); 
db.AssertWasCalled(x => x.SubmitChanges()); 

它仍然每次都返回相同的列表。對於很多情況,這就足夠了。你仍然可以在第二getTable調用返回的其他數據:

db.Stub(x => db.getTable).Return(testdata1); 
db.Stub(x => db.getTable).Return(testdata2); 

它總是具體到一個單一的測試,但是這使得它如此簡單。

編輯:

我不得不承認,我不熟悉的LINQ2SQL。在我的例子中被模擬的調用是Linq2Sql調用,這可能不容易被模擬。您可能需要將其放在簡單的DAL界面之後。然後你嘲笑這個界面。