如何为poco对象创建测试

时间:2010-04-15 13:41:01

标签: c# unit-testing testing mocking

我是嘲笑/测试的新手,想要知道测试时应该达到什么级别。例如,在我的代码中,我有以下对象:

public class RuleViolation
{
    public string ErrorMessage { get; private set; }
    public string PropertyName { get; private set; }

    public RuleViolation( string errorMessage )
    {
        ErrorMessage = errorMessage;
    }

    public RuleViolation( string errorMessage, string propertyName )
    {
        ErrorMessage = errorMessage;
        PropertyName = propertyName;
    }
}

这是一个相对简单的对象。所以我的问题是:

是否需要进行单元测试?

如果它做了我测试的内容以及如何测试?

由于

5 个答案:

答案 0 :(得分:9)

它不包含任何逻辑=>无需测试

答案 1 :(得分:4)

我想说可能不是。您可能想要验证的唯一重要的是访问修饰符:

public string ErrorMessage { get; private set; }
public string PropertyName { get; private set; }

如果真正重要的是,类外部的代码无法修改它们,那么我可能会尝试验证它。

以下是如何在属性中获取访问者:

class Program
    {
        static void Main(string[] args)
        {
            var property = typeof(Test).GetProperty("Accessor");

            var methods = property.GetAccessors();
        }
    }



    public class Test
    {
        public string Accessor
        {

            get;
            private set;
        }    

    }

使用property.GetAccessors();

你可以看看是否有设置者。如果是,那么setter是公开的。 (您还可以使用IsPrivate和IsPublic属性来验证其他访问者。)

答案 2 :(得分:1)

可以对这个对象进行单元测试,但它很简单,不需要它。测试类似于(NUnit示例)

[Test]
public void TestRuleViolationConstructorWithErrorMessageParameterSetsErrorMessageProperty() {
    // Arrange
    var errorMessage = "An error message";

    // Act
    var ruleViolation = new RuleViolation(errorMessage);

    // Assert
    Assert.AreEqual(errorMessage, ruleViolation.ErrorMessage);
}

编写像这样的测试没有什么价值,但是,正如您测试.NET框架的属性是否正常工作一样。一般来说,你可以相信微软有这个权利: - )

关于模拟,当您的测试类具有依赖关系(可能是您自己的应用程序中的另一个类)或框架中的类型时,这非常有用。模拟框架允许您在依赖项上调用方法和属性,而无需在代码中具体构建依赖项,而是允许您为属性注入定义的值,返回方法的值等。Moq是一个很好的框架,以及对具有依赖关系的基本类的测试看起来像这样:

[Test]
public void TestCalculateReturnsBasicRateTaxForMiddleIncome() {
    // Arrange
    // TaxPolicy is a dependency that we need to manipulate.
    var policy = new Mock<TaxPolicy>();
    bar.Setup(x => x.BasicRate.Returns(0.22d));

    var taxCalculator = new TaxCalculator();

    // Act
    // Calculate takes a TaxPolicy and an annual income.  
    var result = taxCalculator.Calculate(policy.Object, 25000);

    // Assert
    // Basic Rate tax is 22%, which is 5500 of 25000.
    Assert.AreEqual(5500, result);
}  

TaxPolicy将在其自己的夹具中进行单元测试,以验证其行为是否正确。在这里,我们要测试TaxCalculator是否正常工作,因此我们模拟TaxPolicy对象以使我们的测试更简单;通过这样做,我们可以指定我们感兴趣的TaxPolicy位的行为。没有它,我们需要创建手动模拟/存根/假货,或创建TaxPolicy的真实实例来传递。

然而,对于Moq来说,还有更多的东西;查看quick-start tutorial以了解更多可以执行的操作。

答案 3 :(得分:1)

如果是我的代码和我的对象,我会对它进行测试,无论课程多么简单或复杂,期间。即使课程似乎不太可能破坏,测试也是IMO在哪里记录您的假设,设计决策和正确使用。

通过这样做,您不仅可以验证您的工作是否符合预期,而且您还有机会思考典型情况(如果ctor参数为空或空或者末尾有空格,会发生什么?为什么不可变类中的PropertyName可选吗?)。

并且IF(何时?)要求发生变化,你有一个坚实的起点来解决这个问题。如果这个琐碎的课程不能与所有其他课程很好地互动,那么你可能需要在客户做之前进行测试。

这是设计代码的正确方法。

HTH,
Berryl

答案 4 :(得分:0)

即使很简单,你的构造函数也有逻辑。我会测试一下:

RuleViolation ruleViolation = new RuleViolation("This is the error message");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.IsEmpty(ruleViolation.PropertyName);

RuleViolation ruleViolation = new RuleViolation("This is the error message", "ThisIsMyProperty");
Assert.AreEqual("This is the error message", ruleViolation.ErrorMessage);
Assert.AreEqual("ThisIsMyProperty", ruleViolation.PropertyName);