【问题标题】:Nsubstitute: Mocking an object Parameter for Unit TestingNsubstitute:模拟单元测试的对象参数
【发布时间】:2017-03-24 07:11:10
【问题描述】:

我对 Nsubstitute 和单元测试还很陌生。 我知道在单元测试中,您不关心任何其他依赖项。因此,为了应用此规则,我们模拟单元。

我有这个例子要测试的代码,其中一个方法有一个对象参数:

class dependency {
  public int A;
  public dependency() {
    // algorithms going on ...
    A = algorithm_output;
  }
}

class toTest {
  public int Xa;
  public void Foo(dependency dep_input){
    Xa = dep_input.A;
    // Xa will be used in an algorithm ...
  }
}

我正在考虑模拟构造函数,但我不知道如何在 Nsubstitute 中。 那么最终,我将如何测试呢?

【问题讨论】:

  • 你只能用 NSubstitute 模拟接口和虚拟方法。构造函数是不行的,非虚拟或静态方法也是如此。也许你应该在你的类中添加一个接口?
  • 如果你想测试它,很可能你想使用一个接口。如果您仍然依赖于实际类,您可能仍然在该类中运行可能会影响您的测试的代码,并且您可能必须小心翼翼地绕过该类中的某些行为以使其适合您的测试.
  • 如果我无法更改要测试的代码(由于我正在从事的项目中的某些原因)怎么办? @LasseV.Karlsen
  • 如果你真的不能改变现有的代码,你就不能模拟类dependency。如果您可以更改类dependency,您可以添加一个接口Idependencyint A;,并将Foo 的ctor 更改为public void Foo(Idependency dep_input)。现在您可以模拟或为dep_input创建存根
  • 代码必须经过设计才能进行测试。许多遗留代码无法简单地进行测试,因为它从未被设计为允许它。如果您无法更改代码,并且虚拟“足够”来处理您想要使用它进行的测试,那么您的代码就属于这一类。您将不得不承担不测试它的风险,以及更改代码的成本和风险。如果你根本不可能在你的梦想中改变代码,并且它在当前形式下是不可测试的,那么答案就是:你不能自动测试它。增加手动测试来弥补。

标签: c# unit-testing nunit nsubstitute


【解决方案1】:

因为太长无法添加评论,所以我添加一个答案: 如果你想测试Foo,你不需要模拟ctor,而是dep_input。例如,如果您使用Moq。但你也可以使用存根

public interface IDependency
{
    int A { get; }
}

public class Dependency : IDependency
{
    public int A { get; private set; }

    public Dependency()
    {
        // algorithms going on ...
        A = algorithm_output();
    }

    private static int algorithm_output()
    {
        return 42;
    }
}

public class ToTest
{
    public int Xa;

    public void Foo(IDependency dep_input)
    {
        Xa = dep_input.A;
        // Xa will be used in an algorithm ...
    }
}

[TestFixture]
public class TestClass
{
    [Test]
    public void TestWithMoq()
    {
        var dependecyMock = new Mock<IDependency>();
        dependecyMock.Setup(d => d.A).Returns(23);

        var toTest = new ToTest();
        toTest.Foo(dependecyMock.Object);

        Assert.AreEqual(23, toTest.Xa);
        dependecyMock.Verify(d => d.A, Times.Once);
    }

    [Test]
    public void TestWithStub()
    {
        var dependecyStub = new DependencyTest();

        var toTest = new ToTest();
        toTest.Foo(dependecyStub);

        Assert.AreEqual(23, toTest.Xa);
    }

    internal class DependencyTest : IDependency
    {
        public int A
        {
            get
            {
                return 23;
            }
        }
    }
}

【讨论】:

  • 啊!这是一个非常有用的例子。谢谢! @Dominik
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 1970-01-01
相关资源
最近更新 更多