2013-03-19 88 views
0

我有一個CSV類和一個CSV解析器類,以及它們的單元測試。我想看看單元測試的一部分,下面必須拆除:要進行單元測試還是不要單元測試此部分

public class CSV{ 

public string[] columns GetColumns() 
     {      
      var columns = null; 

      if (!string.IsNullOrEmpty(this.textReader.ReadLine())) 
      { 
       var columns = this.csvParser.GetColumns(line);    
      } 

      return columns; 
     } 



    } 

    [Test] 
     public void GetColumns_ReturnsCorrectLine() 
     {    
      reader.Setup(r => r.ReadLine()).Returns("a\tb\tc"); 


      //Act 
      var columns = csvReader.GetColumns(); 

      //Assert 
      Assert.IsTrue(columns!=null); 
      Assert.AreEqual(3, columns.Length); 

      Assert.AreEqual("a", columns[0]); 
      Assert.AreEqual("b", columns[1]); 
      Assert.AreEqual("c", columns[2]); 
     } 

問題

1)必須的三條線是斷言列(代碼A,B,C)被刪除?

2)是否GetColumns_ReturnsCorrectLine測試方法去掉最後三個斷言

後進行正確的單元測試請注意,已經有單元測試的CSV解析器的GetColumns()方法的代碼。 GetColumns的功能是解析製表符分隔的字符串並將其轉換爲列。

任何想法?

回答

1

看起來,如果你想測試CSV.GetColumns()。

GetColumns()具有三個路徑

1)textReader.ReadLine()返回null =>返回null
2)textReader.ReadLine()返回 「」=>返回null
3)testReader .ReadLine()返回!string.NullOrEmpty()=>返回CsvParser的輸出。

三個測試應當是

的TextReader返回null =>結果爲空
的TextReader返回 「」=>結果爲空
TestReader返回=>結果是CsvParser的返回值。

由CsvParser返回的值並不重要 - 你提到,該CsvParser它的工作正常進行的其他地方進行測試 - 我們只想說,我們返回解析器的輸出。

public interface ITextReader { 
    string ReadLine(); 
} 

public interface ICsvParser { 
    string[] GetColumns(string line); 
} 

public class CSV { 
    private readonly ITextReader textReader; 
    private readonly ICsvParser csvParser; 

    public CSV(ITextReader textReader, ICsvParser csvParser) { 
     this.textReader = textReader; 
     this.csvParser = csvParser; 
    } 

    public string[] GetColumns() {      
     string[] columns = null; 
     var line = this.textReader.ReadLine();   

     if (!string.IsNullOrEmpty(line)){ 
      columns = this.csvParser.GetColumns(line);    
     } 

     return columns; 
    } 

} 

[TestClass] 
public class CSVFixture { 
    private Mock<ITextReader> mockTextReader; 
    private Mock<ICsvParser> mockCsvParser; 
    private CSV csv; 

    private readonly static string [] Columns = new string[]{}; 

    [TestInitialize] 
    public void Setup() { 
     mockTextReader = new Mock<ITextReader>(); 
     mockCsvParser = new Mock<ICsvParser>(); 
     csv = new CSV(mockTextReader.Object, mockCsvParser.Object); 
    } 


    [TestMethod] 
    public void NullLine() { 
     Execute(null); 
    } 

    [TestMethod] 
    public void EmptyLine() { 
     Execute(""); 
    } 

    [TestMethod] 
    public void PopulatedLine() { 
     Execute("SomeLineValue", Columns); 
    } 

    private void Execute(string line, string[] expected = null) { 
     mockTextReader.Setup(mk => mk.ReadLine()).Returns(line); 
     mockCsvParser.Setup(mk => mk.GetColumns(line)).Returns(Columns); 

     var actual = csv.GetColumns(); 

     Assert.AreEqual(actual, expected); 

    } 
} 

其他景點:只要CsvParser只從這裏調用它只是到處移動的代碼,但這樣,如果輸入的是null或空返回null,你可能會改變CsvParser。這意味着每次調用CsvParser時都不必檢查它。

+0

謝謝你的建議。你說GetColumns()有三條路徑。當ReadLIne返回NULL和string.empty時,兩者是相同的路徑,而不是兩個路徑。但是,它可能被認爲是兩種不同的情況。好東西。我想知道更多關於單元測試的內容。我想知道你是否可以重新閱讀材料。非常感謝。 – Pingpong 2013-03-19 20:34:12

+0

@pingpong我推薦由Roy Osherove撰寫的「單元測試的藝術」和由Michael Feathers撰寫的「遺產代碼有效工作」。此外,只需通過問題和答案在這裏閱讀:) – AlanT 2013-03-20 09:10:04

+0

謝謝。我讀過「單元測試的藝術」。我知道基礎知識。我想深入瞭解。不是WEWLC比Steve Freeman更好的'面向對象軟件,通過測試引導'。如果兩者都好,我應該先閱讀哪一個?特別是,我想知道應該或不應該單元測試什麼,等等。與此同時,我正在網上撰寫相關主題。但我仍然喜歡書籍。 – Pingpong 2013-03-20 10:12:49

1

必須將斷言列(a,b,c)的三行代碼刪除?

TL;博士:沒有

如果你想確保 「一\ TB \ TC」 結果[ 「A」, 「B」, 「C」]而不是[」 b「,」a「,」c「],那麼你應該讓他們進來。前兩行只檢查它是否爲空,長度,內容可以是任何東西。

請注意,已經有代碼單元測試CSV 解析器的GetColumns()方法。

這些測試是什麼?很難說如果他們沒有看到他們重疊。

+0

GetColumns的功能是解析製表符分隔的字符串並將其轉換爲列。正因爲如此,我認爲應該刪除這三行。 – Pingpong 2013-03-19 08:29:21

+0

其實我錯了,請看AlanT的回答。 – valentinas 2013-03-19 19:36:15

2

這些值應該檢查,但不像你在做什麼。

隨着NUnit的,有CollectionAssert

CollectionAssert.AreEqual(new [] {"a", "b", "c"}, columns);