我是......在单元测试方面的初学者。
我刚读了一些单元测试最佳实践。有点理解,单元测试旨在防止对代码造成的破坏应用程序的更改。我们希望在所有对象的公共API(getter,方法)上创建测试用例,以测试对象的行为,看看是否符合我们的预期。
所以现在......我有一个我需要测试的简单类:
public class Foo{
private readonly string _text;
public Foo(string initialText)
{
this._text = initialText;
}
public string Text {get;}
//Some other methods that will use this Text property to parsing, comparasion etc
public string RichTextFormat {....}
}
在这里,就像在评论中一样,这个 Text 属性用于解析,比较等很多地方。
所以我认为确保 Text 属性返回我在构造函数中传递的内容非常重要。
以下是我写的测试案例......
[TestMethod]
public void Text_WhenInitialTextIsNull()
{
string initalizeText = null;
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
[TestMethod]
public void Text_WhenInitialTextIsEmpty()
{
string initalizeText = string.Empty;
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
[TestMethod]
public void Text_WhenInitialTextIsOneLetter()
{
string initalizeText = "A";
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
[TestMethod]
public void Text_WhenInitialTextIsOneSpecialCharacter()
{
string initalizeText = "!";
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
[TestMethod]
public void Text_WhenInitialTextIsOneSentense()
{
string initalizeText = "Hello, World!";
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
[TestMethod]
public void Text_WhenInitialTextIsOneParagraph()
{
string initalizeText = "Who's the Smartphone Winner? " + System.Environment.NewLine +
" On the smartphone front, however, iSuppli put Apple at number one," +
" while Strategy Analytics pointed to Samsung. " + System.Environment.NewLine +
" According to iSuppli, Apple shipped 35 million smartphones in the first quarter" +
" to Samsung's 32 million. Strategy Analytics, however, said Samsung's total was" +
" 44.5 million to Apple's 35.1 million. Nokia landed at number three on both lists" +
" with 12 percent market share. ";
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
我想知道这是不是太重了?
答案 0 :(得分:4)
所以我认为确保Text属性返回我在构造函数中传递的内容非常重要。
这是一个吸气剂。它会在构造函数中设置您看到的_text
字段。
执行任何事情,而不是在初始化类之后检查从getter返回的值是否过度,甚至可以考虑测试不需要测试的内容。
测试基本C#功能是否按预期工作没有意义......
答案 1 :(得分:2)
由于您没有操纵传入的值,我建议您进行一次测试以确保正确设置该值。鉴于此,以下测试就足够了。
[TestMethod]
public void TextReturnsTextPassedToConstructor()
{
string text = "A string";
Foo foo = new Foo(text);
Assert.AreEqual(text, foo.Text);
}
如果构造函数中还有其他逻辑或字符串操作,那么只需要添加其他测试。例如,如果您在字符串为null或为空时抛出异常,或者您正在进行字符替换等。
答案 2 :(得分:0)
我认为您需要更改测试的上下文。我的意思是不要将测试集中在Text
属性上,而是这样做:
[TestMethod]
public void given_null_string_expect_null()
{
string initalizeText = null;
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
[TestMethod]
public void given_special_character_string_expect_that_character()
{
string initalizeText = "!";
Foo realFoo = new Foo(initalizeText);
Assert.AreEqual(initalizeText, realFoo.Text);
}
等等。
重点是:如果您将属性的名称从Text
更改为其他内容会发生什么?您现在需要重新命名以进行大量的单元测试。我的建议是你根据发生的事情的上下文命名测试(例如,给定一个字母的字符串,期望该字母)。这样,如果重命名代码中的内容,则测试不会受到影响。
我的另一点是你不需要在这个级别进行测试。物业真的不值得你花时间去测试。相反,你最好的测试方法或与其他类集成,而不仅仅是属性。
答案 3 :(得分:0)
鉴于您的财产的简单性质,我认为这有点矫枉过正。对于字符串的近乎平凡的测试,我喜欢将它保持在3个测试:null,empty,something。
[TestMethod]
public void Test_Text_Null()
{
Assert.AreEqual(null, new Foo(null).Text);
}
[TestMethod]
public void Test_Text_Empty()
{
Assert.AreEqual("", new Foo("").Text);
}
[TestMethod]
public void Test_Text_Something()
{
Assert.AreEqual("abc", new Foo("abc").Text);
}
一般来说,我不会尝试对这些简单事物的每种可能的输入变化进行单元测试。如果你将来遇到一个bug,因为有人修改了Foo,现在当你在那里有逗号时它会中断 - 然后将其添加到你的单元测试套件中。沿途的单元测试很好 - 但是不要让它瘫痪你继续完成项目的能力。