0

我希望我的单元测试涵盖我的 POCO。

我应该如何测试它们?

如果我添加一个新属性怎么办?如何让我的测试失败?

测试我知道的属性和方法,但问题是,如何确保我的测试失败是将任何东西添加到我的 poco 中。

4

5 回答 5

4

测试就是验证所写的内容是否能够做它应该做的事情,不多也不少。所以如果你写一些代码,你这样做是有原因的。您的测试应该反映代码确实与您编写代码的原因相匹配。就是这样,没有别的了。Iow:如果你写了一堆类,你应该测试你写的行为与行为应该做的相比是否确实正确。

于 2009-05-26T12:36:00.010 回答
3

通过阅读您的问题,您要么误解了 POCO 是什么,要么误解了单元测试。

POCO 只是一个老式的对象。它有状态和行为。您通过将(设置)值放入属性中并断言该值是您期望的值来对状态进行单元测试。您通过针对方法断言期望来对行为进行单元测试。

这是 POCO 及其测试的过度简化示例。请注意,测试代码多于实现代码。当单元测试正确完成(TDD)时,就是这种情况。

public class Person
{
    private Name name = Name.Empty;
    private Address address = Address.Empty;
    private bool canMove;

    public Name Name
    {
        set { name = value; }
        get { return name; }
    }

    public Address Address
    {
        private set { address = value; }
        get { return address; }
    }

    public bool CanMove
    {
        set { canMove = value; }
        get { return value; }
    }

    public bool MoveToNewAddress(Address newAddress)
    {
        if (!CanMove) return false;
        address = newAddress;
        return true;
    }
}

[TestFixture]
public class PersonTests
{
    private Person toTest;
    private readonly static Name NAME = new Name { First = "Charlie", Last = "Brown" };
    private readonly static Address ADDRESS =
        new Address {
            Line1 = "1600 Pennsylvania Ave NW",
            City = "Washington",
            State = "DC",
            ZipCode = "20500" };

    [SetUp]
    public void SetUp()
    {
        toTest = new Person;
    }

    [Test]
    public void NameDefaultsToEmpty()
    {
        Assert.AreEqual(Name.Empty, toTest.Name);
    }

    [Test]
    public void CanMoveDefaultsToTrue()
    {
        Assert.AreEqual(true, toTest.CanMove);
    }

    [Test]
    public void AddressDefaultsToEmpty()
    {
        Assert.AreEqual(Address.Empty, toTest.Address);
    }

    [Test]
    public void NameIsSet()
    {

        toTest.Name = NAME;
        Assert.AreEqual(NAME, toTest.Name);
    }

    [Test]
    public void CanMoveIsSet()
    {
        toTest.CanMove = false;
        Assert.AreEqual(false, toTest.CanMove);
    }

    [Test]
    public void AddressIsChanged()
    {
        Assert.IsTrue(toTest.MoveToNewAddress(ADDRESS));
        Assert.AreEqual(ADDRESS, toTest.Address);
    }

    [Test]
    public void AddressIsNotChanged()
    {
        toTest.CanMove = false;
        Assert.IsFalse(toTest.MoveToNewAddress(ADDRESS));
        Assert.AreNotEqual(ADDRESS, toTest.Address);
    }
}

为了使测试首先失败,存根方法或属性,但不实现任何行为。运行测试,观察它们失败,然后一次添加一行,直到它通过。一旦过去,停下来。除非您编写更多测试,否则不要编写更多代码(除非您正在重构,在这种情况下您不添加行为)。

于 2009-05-26T12:38:08.680 回答
1

如果你想在类中添加一个新特性,写一个因为特性没有实现而失败的测试,然后实现这个特性,看看测试通过了。

或者...

在构建过程中运行代码覆盖率指标。它们将指示是否添加了代码气体而没有被测试覆盖。

或者...

作为构建的一部分运行突变测试。他们将指出是否有任何覆盖代码的测试只是通过它而不是实际测试任何东西。

或以上所有。

于 2009-05-26T12:35:11.057 回答
1
  1. 我相信您不应该将框架与您自己的代码一起测试,例如,如果您有这样的自动生成属性:

    public string Name
    {get;set;}
    

    没有必要有一个测试方法来查看它是否工作正常。

  2. 你不应该测试你的类的内部状态,而应该测试它的行为。
  3. 有时(有些人可能总是说)最好在编写代码之前编写测试。这样你必须了解你想要做什么而不是了解如何去做。(这种方法称为测试驱动开发)

这是TDD循环:

  • 编写测试并获得红色信号
  • 编写代码并获得绿色信号
  • 重构代码,你应该得到一个绿色信号
于 2009-05-26T14:10:25.887 回答
1

也许您所说的 POCO 是指 DTO,在这种情况下,答案是:

不,您不应该测试您的 DTO,而是测试与它们一起工作的服务。

于 2009-05-26T15:52:40.160 回答