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

任何的想法?

4

3 回答 3

2

应该检查这些值,但不像你正在做的那样。

使用 NUnit,有CollectionAssert

CollectionAssert.AreEqual(new [] {"a", "b", "c"}, columns);
于 2013-03-19T01:03:21.653 回答
2

看起来好像您正在尝试测试 CSV.GetColumns()。

GetColumns()有三个路径

1) textReader.ReadLine() 返回 null => return null
2) textReader.ReadLine() 返回 "" => return null
3) testReader.ReadLine() 返回 !string.NullOrEmpty() => 返回 CsvParser 的输出。

三项测试应该是这样

TextReader 返回 null => 结果为 null
TextReader 返回 "" => 结果为 null
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,它只会移动代码,但您可以更改 CsvParser,以便如果输入为 null 或为空,则返回 null。这意味着您不必在每次调用 CsvParser 时都检查它。

于 2013-03-19T11:29:28.717 回答
1

必须删除断言列 (a,b,c) 的三行代码吗?

tl;博士:没有

如果你想确保 "a\tb\tc" 结果是 ["a", "b", "c"] 而不是 ["b", "a", "c"],那么你应该离开它们前两行只检查它是否不为空,长度,内容可以是任何东西。

请注意,已经有代码可以对 CSV 解析器的 GetColumns() 方法进行单元测试。

那些测试是什么?如果没有看到它们,很难判断它们是否重叠。

于 2013-03-19T01:00:12.573 回答