2016-02-29 91 views
0

如何創建部分使用數據庫單元測試但從常規單元測試中調用的單元測試?數據庫操作作爲單元測試的先決條件?

是的,也許他們可能不是單元測試;你可能希望稱它們爲集成測試。無論你想標註什麼,他們都是測試。

在我的NUnit的測試中,我使用輔助常數:

private const string NumericSerial="123123"; 
private const string NonNumericSerial="123123 bad serialnumber"; 
private const int ValidPatientId=123; 
private const int InvalidPatientId=-1; 
private const int PatientIdThatDoesNotExistInppp=111291; 
private const string SerialNumberThatDoesNotExistInshmk="123123"; 
private const string SerialNumberThatDoesExistInshmk="1015873"; 
private const byte InvalidFirmwareVersion=0; 
private const int FacilityThatDoesntExistInAAA=Int32.MaxValue; 

此前運行使用這些常量的任何測試,我想確認這些恆定的正確定義。

例如,我可以斷言NumericSerial的確是數字,而不必做任何嘲弄或注入任何依賴關係 - 我只是簡單地嘗試它。

然而,其他常量如PatientIdThatDoesNotExistInppp將需要驗證它確實在PPP數據庫中不存在。爲了做到這一點,我可以遵循以下幾個途徑:

  1. 實現實體框架LINQ查詢
  2. 明確首先創建發送select語句的數據庫
  3. 或者我可以一個數據庫單元測試必要的記錄(在我們的情況下,它會確保111291不存在於數據庫中。

除非你對選項#3強烈建議,我傾向於實現這一點。如何創建一個單元測試,部分利用數據庫單元測試,但從常規單元測試中調用?

我尋找類似以下內容:

[Test] 
public response_from_database_unit_test_equals_111291() 
{ 
//call the database unit test 
//retrieve value from database unit test 
} 
+0

您是否首先使用Entity Framework代碼作爲您的數據訪問層,根本沒有存儲過程?如果是的話,那麼有一種很好的方式來進行數據測試,而不會觸及數據庫,但數據層具有100%的可靠性。讓我知道。 –

+0

我不是id愛聽如何進行這種方式 –

+0

通過「這樣」我假設你的意思是你的問題,所以我已經回答了 –

回答

1

這裏是你請求的基於純粹的實體框架

[TestMethod] 
    public void GetAllBlogs_Orders_By_Name() 
    { 
     var data = new List<Blog> 
     { 
      new Blog { Name = "BBB" }, 
      new Blog { Name = "ZZZ" }, 
      new Blog { Name = "AAA" }, 
     }.AsQueryable(); 

     var mockSet = new Mock<DbSet<Blog>>(); 

     mockSet.As<IQueryable<Blog>>().Setup(m => m.Provider).Returns(data.Provider); 
     mockSet.As<IQueryable<Blog>>().Setup(m => m.Expression).Returns(data.Expression); 
     mockSet.As<IQueryable<Blog>>().Setup(m => m.ElementType).Returns(data.ElementType); 
     mockSet.As<IQueryable<Blog>>().Setup(m => m.GetEnumerator()).Returns(0 => data.GetEnumerator()); 

     // we tell EF that treat our data list as the table of Blogs. 
     var mockContext = new Mock<BloggingContext>(); 
     mockContext.Setup(c => c.Blogs).Returns(mockSet.Object); 

     // make EF query the blogs table (i.e. our list) 
     var context = mockContext.Object; 

     // EF has queried our list here 
     // you could run Select, OrderBy, Where etc. as well 
     var blogs = context.Blogs.ToList(); 

     Assert.AreEqual(3, blogs.Count); 
     Assert.AreEqual("AAA", blogs[0].Name); 
     Assert.AreEqual("BBB", blogs[1].Name); 
     Assert.AreEqual("ZZZ", blogs[2].Name); 
    } 

我沒有寫這個樣品額外的答案。它是直接從https://msdn.microsoft.com/en-us/library/dn314429.aspx(因此所有信貸MSDN)

重點在於,在數據庫涉及0%的情況下,我們讓Entity Framework知道「hey EF!tre在我的列表中。「 EF然後在列表中運行所有實際查詢(Where,Select,OrderBy,GroupBy等)。設置這個列表非常微不足道。 (包括嵌套鏈接)

您的數據層代碼將始終包含在本單元測試中。 當涉及到實際表時,您可以信任EF來進行正確的SQL調用。

p.s.唯一的兩件事,我注意的是包括子句和DbFunctions。這2個行爲在本地列表和實際表之間有所不同。但是一旦你注意到了這兩件事情,單元測試你的數據層到這種程度是一件令人愉快的事情,根本不用擔心真正的數據庫。

+0

這是驚人的,但在什麼時候可以對數據運行選擇查詢? –

+0

我不知道男人我真的很苦惱這個:https://drive.google.com/file/d/0ByqKtGmtuLzZUGVNVkdVaDYzOGc/view?usp=drivesdk –

+0

你設置錯誤的設備..使用此var mockContext = new模擬(); mockContext.Setup(c => c.Devices).Returns(mockSet.Object); –

1

如果你想要做的數據庫相關的測試,然後有一對夫婦的,使人們對你更容易的選擇。 (它不會是100%,無褶皺,因爲DB測試是不平凡)

  1. 在您的測試類的[Setup]方法,建立一個新的事務範圍,並設置任何先決條件,你需要。 (有無記錄)
  2. 在實際的測試案例中,使用Linq2Sql或EF LINQ做驗證。它非常高效並且避免了討厭的SQL /存儲過程。
  3. [Teardown]方法中,完成提交事務的範圍。

如有任何異常,交易將自然回滾。

而不是一個單元測試調用數據庫單元測試,將通用代碼提取爲常用方法,並將它們稱爲數據庫測試和這些測試。 (例如GetRecordWithId(5678))

這樣,您的測試並不真的依賴數據庫單元測試,但共享數據訪問代碼。

而當你正確提到的,不要緊,你把這些東西..他們也許

我們可以做我們的最好的數據測試和集成測試等(不一定是單元測試),以保持狀態使用事務範圍,但最終連接問題,並行測試執行,連接到公用數據服務器(或本地SQL Server先決條件)的開發服務器上的測試執行,在構建服務器上測試執行等最終實現數據庫清理。數據庫測試,當涉及實際的數據庫時。

許多團隊都採用一種策略來建立一個特定於測試運行的新數據庫[prefix + timestamp],以便它不會與其他運行衝突。並在最後撕下分貝。 (最糟糕的情況是,有一個後臺進程,它監視具有特定前綴名稱的數據庫,並根據時間戳在每個午夜進行清理,正如您所看到的,有很多外圍工作要做,對於測試的價值數據層。

+0

一如既往地感謝您的親切,全面的反饋。你能指點我一個例子,顯示這種類型的測試從頭到尾,或者只是[設置]? –

+0

raja我會非常感謝,如果你還可以包括一個例子使用交易範圍 –

+0

這是否有幫助? http://stackoverflow.com/questions/321180/how-do-i-test-database-related-code-with-ununit –