我应该在一个简单的get属性上测试多么沉重?

时间:2012-04-27 14:55:49

标签: c# unit-testing

我是......在单元测试方面的初学者。

我刚读了一些单元测试最佳实践。有点理解,单元测试旨在防止对代码造成的破坏应用程序的更改。我们希望在所有对象的公共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);
}

我想知道这是不是太重了?

4 个答案:

答案 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,现在当你在那里有逗号时它会中断 - 然后将其添加到你的单元测试套件中。沿途的单元测试很好 - 但是不要让它瘫痪你继续完成项目的能力。