要进行单元测试还是不要单元测试此部分

问题描述:

我有一个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的功能是解析制表符分隔的字符串并将其转换为列。

任何想法?

看起来,如果你想测试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

必须将断言列(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

这些值应该检查,但不像你在做什么。

随着NUnit的,有CollectionAssert

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