.Net中的单元测试属性?

时间:2009-02-27 07:44:58

标签: c# .net unit-testing testing

我正在开发一个我想在开源中发布的lib。我已经开始为代码编写测试了,我想知道我是如何测试.Net对象中的属性的。可以说我有以下内容:


public class Person{
    #region variables
    private string _name = String.Empty;
    private string _surname = String.Empty;
    #region properties
    public string Name{
        get{
             return _name;
        }
    }
    public string Surname{
        get{
            return _surname;
        }
        set{
            _surname = value;
        }
    }
}

我有两个与代码相关的问题:

  1. 如何对仅具有getter的属性进行单元测试(与示例中的Name一样)
  2. 如何使用setter和getter对Property进行单元测试(如示例中的Surname)
  3. 我想测试那么简单的属性,因为我已经在其他代码中发现了错误,Itellinsense做错了自动完成,而且属性没有返回正确的变量。

    更新:

    我不是说简单的属性就像示例中那样,它们背后有一些逻辑并且很难调试。编写使用setter来测试getter的测试,反之亦然,因为如果出现故障,我不知道应该指责哪种方法。我正在使用属性,因为它们被添加为公共变量,后来需要添加更多逻辑。

9 个答案:

答案 0 :(得分:9)

  不要浪费你的时间写傻   测试getter和setter。

     

另一项测试可能会设置   命名,然后获得该属性,所以你   将有代码覆盖   吸气剂。

您应该测试任何公共场景,包括属性。如果您不测试属性,则可能会冒一些人在其中添加一些逻辑,从而破坏功能的风险。

此外,您不应该依赖它在其他测试中进行测试。这会使您的测试变得脆弱,并且更难以确定问题所在,因为测试将测试不止一件事。

答案 1 :(得分:8)

  

我如何对属性进行单元测试   只是有一个吸气剂(像名字一样)   例如)

如果你有一个二传手,真的没有那么不同于测试。你只需要找到另一种确定输出的方法。可以在ctor中,也可以是对象上其他setter / operations的结果。

[Test]
public void NamePropTest()
{
    Person p = new Person();

    //Some code here that will set up the Person object
    //  so that you know what the name will be

    Assert.AreEqual("some known value...", p.Name);
}

如果我们有Name和SurName的setter,但只有FullName的getter,那么测试可能如下所示:

[Test]
public void NamePropTest()
{
    Person p = new Person();

    p.Name = "Sean";
    p.Surname = "Penn";

    Assert.AreEqual("Sean Penn", p.FullName);
}

答案 2 :(得分:5)

您应该测试属性。也是自动属性!

单元测试是关于确保对程序进行更改,不要破坏程序。

您可能最终会在某个时间更改属性实现,并且您希望确保程序仍然按预期工作。你可以用你的测试来做到这一点。

即使您使用自动属性(作为字段/成员变量的替代),制作属性的原因也是您希望稍后更改其实现的原因。然后你会希望测试在那里。

编辑:(回应shahkalpesh的评论......)

  

如果你正在改变   实施,测试也可能   需要改变。所以,我不知道   为什么有人应该测试简单   获取/设置?

从这个课程开始:

public class TimeOfDay
{
    public int Hour{get; private set;}
    public int Minute{get; private set;}

    public TimeOfDay(int hour, int minute)
    {
        Hour = hour;
        Minute = minute;
    }
}

更改实施时,测试仍然有效!

public class TimeOfDay
{
    public int _minutesSinceMidnight = 0;

    public int Hour
    {
        get { return _minutesSinceMidnight / 60; }
        set { _minutesSinceMidnight = value * 60 + Minutes; }
    }

    public int Minute
    {
        get { return _minutesSinceMidnight % 60; }
        set { _minutesSinceMidnight = Hour * 60 + value; }
    }

    public TimeOfDay(int hour, int minute)
    {
        Hour = hour;
        Minute = minute;
    }
}

投入一些日期和时间算术函数或其他东西,我希望测试表明一切仍然有效......

答案 3 :(得分:3)

我认为你应该测试,如果你像他们一样写它们。毕竟你可以输入错误的东西。

就像

var person = New Person();
person.Surname = "test";
Assert.AreEqual("test", person.Surname);

在所有TDD和单元测试之后,一般都是关于避免大多数错误。

如果不小心你写了这个。

public class Person{
    #region variables
    private string _name = String.Empty;
    private string _surname = String.Empty;
    #region properties
    public string Name{
        get{
             return _name;
        }
    }
    public string Surname{
        get{
            return _name;
        }
        set{
            _name = value;
        }
    }
}

然后你会有一个错误。

测试自动属性可能不太有价值。但这是另一个问题。

答案 4 :(得分:1)

那些属性应该存在,因为你有需要它们的用法。至于这些应该有单元测试,你应该已经有他们的报道。 如果没有需要它们的场景,它们可能根本就不存在。

答案 5 :(得分:1)

据我所知,你不应该测试属性(即那些简单的get / set)。

我不确定您使用的是哪种版本的c#。但是,您可以使用自动属性来避免您遇到的简单的设置/获取问题。

请参阅此link

答案 6 :(得分:1)

Don's浪费你的时间为吸气者和制定者写下愚蠢的测试。

另一个测试可能会设置Name,然后获取该属性,以便您获得getter的代码覆盖率。

答案 7 :(得分:1)

  

我的问题与如何有关   写测试。我一直在想   关于它,我需要访问   私人价值观,以确保   属性按预期工作,否则   我不知道怎么做。   https://stackoverflow.com/users/59332/mandel

好的......因为你坚持知道怎么做......

[Test]
TestMethod()
{

    Person p = new Person();
    p.Name = "a name";
    p.Surname = "a surname";

    Assert.That(p.Name, Is.EqualTo("a name"));
    Assert.That(p.Surname, Is.EqualTo("a surname"));
}

然而,这只有在你有制定者的情况下才有效....

如果你只有吸气剂,我只能想到你可以做到的两种方式。

  1. 事先知道返回值并断言。
  2. 使用Reflection设置值,然后根据该已知值进行断言。
  3. 更好的建议是放弃并测试有价值的东西,这实际上为您的软件增加了价值。测试getter和setter绝对是浪费时间,除非他们身后发生了一些复杂的事情......这种情况很少发生。

答案 8 :(得分:1)

我认为你的意思是你的getter-only propoerty使用私有字段或其他私人数据。如果你需要设置它们,唯一的方法是通过Reflection获取它们(参见System.Reflection中的所有(某些)Info类)。但如果这是一个很好的做法,那就很难讨论。