要进行单元测试还是不要单元测试此部分
我有一个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时都不必检查它。
必须将断言列(a,b,c)的三行代码删除?
TL;博士:没有
如果你想确保 “一\ TB \ TC” 结果[ “A”, “B”, “C”]而不是[” b“,”a“,”c“],那么你应该让他们进来。前两行只检查它是否为空,长度,内容可以是任何东西。
请注意,已经有代码单元测试CSV 解析器的GetColumns()方法。
这些测试是什么?很难说如果他们没有看到他们重叠。
GetColumns的功能是解析制表符分隔的字符串并将其转换为列。正因为如此,我认为应该删除这三行。 – Pingpong 2013-03-19 08:29:21
其实我错了,请看AlanT的回答。 – valentinas 2013-03-19 19:36:15
这些值应该检查,但不像你在做什么。
随着NUnit的,有CollectionAssert
:
CollectionAssert.AreEqual(new [] {"a", "b", "c"}, columns);
谢谢你的建议。你说GetColumns()有三条路径。当ReadLIne返回NULL和string.empty时,两者是相同的路径,而不是两个路径。但是,它可能被认为是两种不同的情况。好东西。我想知道更多关于单元测试的内容。我想知道你是否可以重新阅读材料。非常感谢。 – Pingpong 2013-03-19 20:34:12
@pingpong我推荐由Roy Osherove撰写的“单元测试的艺术”和由Michael Feathers撰写的“遗产代码有效工作”。此外,只需通过问题和答案在这里阅读:) – AlanT 2013-03-20 09:10:04
谢谢。我读过“单元测试的艺术”。我知道基础知识。我想深入了解。不是WEWLC比Steve Freeman更好的'面向对象软件,通过测试引导'。如果两者都好,我应该先阅读哪一个?特别是,我想知道应该或不应该单元测试什么,等等。与此同时,我正在网上撰写相关主题。但我仍然喜欢书籍。 – Pingpong 2013-03-20 10:12:49