2011-08-09 84 views
3

作爲一名BDD和MSpec初學者,我仍然不太確定與BDD有關的最佳實踐和良好習慣,特別是MSpec。MSpec測試可以改進嗎?

下面的例子可以改進嗎?它是否遵循最佳實踐和良好習慣?

  1. 是我的規範類和行爲的命名行嗎?
  2. 我應該在這種情況下使用行爲,還是應該爲規範類使用公共基類?
  3. 可以在這裏沒有Establish嗎?
  4. 我應該使用靜態工廠方法(TestData方法)來獲取測試數據還是應該在規範本身中創建數據?
  5. 而不是測試行爲中的每個屬性我可以使用result.Equals()但我會測試兩件事情,這是不好的,對不對?

請隨意重構這個例子,你會說更好。

[Subject(typeof(DataItemReader))] 
public class When_reading_a_DataItem_from_stream 
{ 
    Because of =() => 
    { 
     using (var reader = new DataItemReader(
      new MemoryStream(TestData.GetNormalDataItemAsByteArray()), Encryption.None)) 
     { 
      result = reader.ReadItem(); 
     } 
    }; 

    Behaves_like<DataItemReader_that_reads_correctly> behavior; 

    protected static DataItem result; 
} 

[Subject(typeof(DataItemReader))] 
public class When_reading_a_DataItem_from_encrypted_stream 
{ 
    Because of =() => 
    { 
     using (var reader = new DataItemReader(
      new MemoryStream(TestData.GetNormalDataItemAsByteArrayEncyrpted()), Encryption.Default)) 
     { 
      result = reader.ReadItem(); 
     } 
    }; 

    Behaves_like<DataItemReader_that_reads_correctly> behavior; 

    protected static DataItem result; 
} 

[Behaviors] 
public class DataItemReader_that_reads_correctly 
{ 
    protected static DataItem result; 

    It should_read_the_correct_DataItem =() => 
    { 
     var testItem = TestData.GetNormalDataItem(); 
     result.Property1.ShouldEqual(testItem.Property1); 
     result.Property2.ShouldEqual(testItem.Property2); 
     result.Property3.ShouldEqual(testItem.Property3); 
    }; 
} 

回答

6

這也許少了些什麼這個世界的看法的規格和更多的你和你的團隊/同行/「人誰也讀這個代碼後,你」可以從中獲益。

從一個開發的角度來看:

  1. 我的外殼和命名遵循什麼在代碼的可讀性。 HTML提取的好處在於最終可以獲得可讀的規格。我讀過的很多內容都着重於全部小寫或者類似的內容;不過,我把我的文字描述得非常像你的:適當的,可讀的外殼。

  2. 對於這樣的一對一行爲,行爲對於可讀性來說是很好的。我使用基類來建立上下文併爲重複的常見斷言設置期望和行爲。

  3. Establish一直意味着「在測試前設置環境」。在你有兩個例子,我可能把它改寫喜歡:

    Establish context =() => var reader = 
         new DataItemReader(new MemoryStream(  
         TestData.GetNormalDataItemAsByteArray()),        
         Encryption.None)); 
    
    Because of =() => result = reader.ReadItem(); 
    
    Cleanup after =() => reader.Dispose(); 
    

    由於該規範的重點是一個DataItem的「讀取」,動作或Because就是這樣。再次,優先事項。

  4. 我使用可重複使用的靜態工廠,我已經手工創建了存根或者有一個存根/模擬引擎(如FakeItEasy http://code.google.com/p/fakeiteasy/)。在我看來,存根(stub)的內容/創建與實際測試幾乎沒有關係,應該將存根視爲黑匣子(這就是爲什麼我們要編寫測試,對吧?)。

  5. 我專注於每個房​​產單獨(如你所知),以確保它們符合我的期望。如果您超過Equals,您可能會檢查不屬於規範或不相關的屬性的平等性。

我不知道有任何管轄「最佳實踐」(也有在github上網站的一些技巧:https://github.com/machine/machine.specifications#readme)。我發現通過使用MSpec查看其他項目並觀察他們如何處理規範,我的編碼風格發生了一些變化。

+0

你可以推薦一些使用MSpec的項目,我可以學習嗎? – bitbonk

+0

對於3.我需要在某處調用'reader.Dispose()'。我應該這樣做:'因爲=()=> try {result = reader.ReadItem(); } finally {reader.Dispose(); }' – bitbonk

+1

關於我的頭頂,Fluent NHibernate(https://github.com/jagregory/fluent-nhibernate)使用MSpec。尋找項目的一個好方法可能是打開github並搜索Code/C#和「使用Machine.Specifications」;通過參考找到所有項目。 :) –

相關問題