【问题标题】:How to unit test a c# method that has dependency on a locally declared object's behavior?如何对依赖于本地声明对象行为的 c# 方法进行单元测试?
【发布时间】:2014-04-01 23:12:06
【问题描述】:

我有一个 c# 方法,它依赖于它使用本地实例化的对象进行的服务调用的返回值。如何在不更改代码的情况下对其进行测试。我知道依赖注入会使其可测试,或者将依赖传递到此方法之外会使其可测试,但这里不是这种情况。

我的方法看起来像这样:

public class Animal
{ 
    int Weight;
    public int CalculateActualWeight()
    {
       var weightFactory = new WeightFactory();
       var weight = Weight + weightFactory.GetEatenAmount();
       return weight;
    }
}

要测试的方法是CalculateActualWeight()。

【问题讨论】:

  • 你可以完全不改变生产代码,或者只是不改变它的外部接口吗?如果你将var weightFactory = new WeightFactory(); 拉到Animal 上的一个函数中,你可以在你的单元测试中自我存根。不是您的最佳选择,但总比无法测试要好。

标签: c# unit-testing dependencies


【解决方案1】:

如果您无法更改生产代码,测试它的唯一方法是编写一个围绕本地实例化对象如何工作的测试。

您也可以使用self stubbing,但这不是推荐的做法,并且仅当被测对象具有可以模拟以替换您需要的功能时才有效。

示例:

[Test]
public void Test()
{
    //do stuff so that a "real" new WeightFactory() will return what you want
    //(this will require you to go figure out how the WeightFactory works), 
    //4 is just an example of your desired result
    SetUpSystemSoThatWeightFactoryProduces(4);

    var testAnimal = new Animal();
    testAnimal.Weight = 14;

    Assert.That(testAnimal.CalculateWeight(), Is.EqualTo(18));
}

【讨论】:

  • 您有没有关于我的示例问题的示例?
  • WeigthFactory 在CalculateActualWeight() 中实例化。所以,我想不出任何方法来设置 WeightFactory.GetEatenAmount() 以返回我想要的,因为它是一个全新的对象,在被测方法内部实例化。
  • 你不能把它存根。您必须查看该函数的实际实现,并尽一切努力设置“系统”以使用真实代码从该函数调用返回您想要的值。
【解决方案2】:

您可以使用 Moq 之类的方法来伪造函数的返回结果。您可以设置它(它是您的测试),以便您的依赖项返回您告诉它返回的任何内容。然后你可以测试依赖的方法,知道其他方法的结果是什么。

var mock = new Mock<IYourClass>();
mock.Setup(m => m.Method()).Returns(true);

这将使您的 Method() 始终返回 true,以便您可以测试另一个。 More info on Moq here.

【讨论】:

  • 这很好。请注意,仅当相关的本地实例化对象是在与被测对象不同的函数中创建时才有效。如果它们在同一个函数中,这将不起作用。
  • 是的,你是对的。我已经更新了我的问题以使其更清楚。
  • 他的编辑现在显示该对象是在同一个函数中创建的。我唯一能说的是,编写代码时最好考虑到可测试性。
猜你喜欢
  • 1970-01-01
  • 2013-02-27
  • 2013-09-26
  • 1970-01-01
  • 2010-10-03
  • 1970-01-01
  • 2014-08-14
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多