【问题标题】:How to create tests for poco objects如何为 poco 对象创建测试
【发布时间】:2010-04-15 13:41:01
【问题描述】:

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

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;
    }
}

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

是否需要单元测试?

如果它可以测试什么以及如何测试?

谢谢

【问题讨论】:

  • 查看我的更新,了解如何检查 setter 是否为私有。

标签: c# unit-testing testing mocking


【解决方案1】:

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

【讨论】:

    【解决方案2】:

    我会说可能不会。如果它非常重要,您可能唯一需要验证的是访问修饰符:

    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 是否存在。如果是,那么 setter 是公开的。 (还有属性 IsPrivate 和 IsPublic 您也可以用来验证其他访问器)。

    【讨论】:

    • +1 这是随着代码的发展而难以注意到的事情,而且测试非常简单,几乎没有理由不测试
    • 你将如何实际测试这样的东西?因为您不能尝试设置属性,因为它显示编译器错误?还是我错过了一些简单的东西?
    • +1 你在这里有非常好的小测试!就像我们喜欢的那样,精益和敏捷!谢谢!
    【解决方案3】:

    如果它是我的代码和我的对象,我会对其进行测试,不管这个类是多么简单或复杂,句号。即使该类似乎不太可能中断,IMO 也是您记录您的假设、设计决策和正确使用的地方。

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

    如果(何时?)需求发生变化,您有一个坚实的起点来解决这个问题。如果这个微不足道的类不能很好地与所有其他类进行交互,那么您可能需要进行测试才能在您的客户之前抓住它。

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

    HTH,
    浆果

    【讨论】:

      【解决方案4】:

      可以对该对象进行单元测试,但它非常简单,不需要它。测试类似于(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 的真实实例来传递。

      然而,起订量远不止于此;查看quick-start tutorial 了解更多它的功能。

      【讨论】:

        【解决方案5】:

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

        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);
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2021-09-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多