自动实现属性的单元测试是否有价值?

8

看起来有些过度了,但根据规定 任何公开可用的内容都应该经过测试,那么自动实现属性是否需要测试呢?

客户类

public class Customer
{
    public string EmailAddr { get; set; }
}

测试者

[TestClass]
public class CustomerTests : TestClassBase
{
    [TestMethod]
    public void CanSetCustomerEmailAddress()
    {
        //Arrange
        Customer customer = new Customer();

        //Act
        customer.EmailAddr = "foo@bar.com";

        //Assert
        Assert.AreEqual("foo@bar.com", customer.EmailAddr);
    }
}
5个回答

10

我通常认为,没有执行任何操作的代码不值得测试。这通常意味着我不会测试属性(自动实现或者非自动实现),因为它们只是设置或返回一个值。

如果属性的getter或setter执行了某种“工作”,比如根据其他字段/属性/任何内容的状态可能返回两个或更多个值,则情况会有所改变。

如果您还没有看过,我强烈推荐参考Roy Osherove《单元测试之道》。它涵盖了各种“何时以及测试什么”的类型问题,包括这个问题。


2
测试自动属性是在测试框架,而不是您的代码:没有代码逻辑需要验证。如果最终在属性后面添加了代码,您应该看到测试覆盖率下降,这将表明现在是测试该属性的时候了。 - Mathias
这比看测试覆盖率下降还要简单...正如我在其他回答中所评论的,如果你改变代码,使其执行的不是自动属性,那么这种改变应该由一个测试驱动,这样你就可以测试这个功能上的变化。 - ckramer

8

如果您从自动实现属性切换到完全不同的东西会发生什么?测试似乎只是多余的,因为您知道实现方式——在编写测试时不应考虑这一点。

当然,这取决于您实际上有多大可能很快更改实现。


4
如果那样的话,你会先写一个测试对吧?这样就可以进行测试了。如果你正在进行TDD(测试驱动开发),那么这将是其工作方式。我们都知道有些人不总是先写测试。 - ckramer
1
+1 是针对回归方面的。虽然今天它是自动属性,但明天可能需要修改以支持新的类特性等等... - Paul Kohler

1

这要看你是测试 API 是否符合预期的属性集,还是像你所演示的那样,只是测试访问和设置属性。

在你给出的例子中,我会说不需要。

更新

如果你间接地访问属性,比如在反射/动态环境中,并且使用属性和方法访问调用来验证未知的 API 是否符合预期的 API,则需要符合预期的 API。


你能详细说明一下“测试API是否符合预期属性集”的含义吗? - ahsteele

1

测试属性的设置和获取应该在测试对象的业务功能的上下文中进行。如果没有业务功能测试该属性,那么要么您不需要该属性,要么您需要更多测试。我建议您在添加需要它们的测试时将属性添加,而不是在编写任何测试之前添加它们。

通过测试业务功能,您将代码视为单元测试的黑盒子。这使您能够在实现细节发生变化时对测试的影响更小。由于重构是TDD周期的一个重要(但经常被忽视)阶段,因此这意味着代码编辑要少得多。您还可能意识到(例如)该属性不应具有公共setter,并且应由执行验证和其他业务逻辑的方法分配。


0

单元测试应该仅限于测试您在应用程序中实现的功能。

您不应该测试应用程序依赖的API/SDK。部分原因是这是浪费时间(您的公司想为您测试X-Third-Party的SDK/API付费吗?),部分原因是它会向您的单元测试套件引入“噪音”。您的单元测试库的上下文应该只是测试应用程序中的代码。


Customer 是我们拥有的一个类。 - ahsteele
@ahsteele,没错,但你的测试可以说只测试了C#编译器的行为。 - Yishai
@Yishai同意了,在重新阅读答案后,我明白了warriorpostman的意思。 - ahsteele

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接