c# - 根据对象的属性而不是其引用模拟设置返回类型

标签 c# unit-testing mocking nsubstitute

由于模拟框架 (NSubstitute) 的工作方式,我在单元测试中遇到了问题。

我想测试一个接收参数的方法,在该方法内部,我使用 new 运算符创建一个新对象,并将这个新对象传递给将构建另一个对象的构建器。我的问题是我无法模拟构建器以返回我想要的内容,因为当我配置返回对象时,它会根据引用来执行此操作。

因此,如果我新创建的对象如下所示:

class MyReferenceType
{
    public String Property1 { get; set; }

    public String Property2 { get; set; }

    public String Property3 { get; set; }
}

如果我的模拟将创建一个 MyReferenceType 类型的新对象,我会这么说

myBuilder.Build(myReferenceTypeObject).Returns(anotherObject);

在我的方法中,对象myReferenceTypeObject将有另一个引用,并且它不会返回我想要的对象。

那么有没有一种方法可以根据对象的属性内容而不是其引用来配置模拟的返回对象?

这是一些代码:

class Mapper
{
    private Builder builder;
    public Mapper(Builder builder)
    {
        this.builder = builder;
    }

    public string Map(string data)
    {
        //process the string 

        MyReferenceType obj = new MyReferenceType();

        return this.builder.Build(obj);
    }
}

最佳答案

无法使引用匹配。您无法在被测方法之外控制该对象,因为它是在方法内初始化的。

使用Arg.Any<T>()让参数在执行时使模拟期望更加灵活,因为它将忽略传递的特定参数。

根据提供的代码示例,一个简单的测试可能如下所示

//Arrange
var data = "some data";
var myBuilder = Substitute.For<Builder>();
var expected = "some value";
myBuilder.Build(Arg.Any<MyReferenceType>()).Returns(expected);

var subject = new Mapper(myBuilder);

//Act
var actual = subject.Map(data);

//Assert
Assert.AreEqual(expected, actual);

这将允许模拟在调用时按预期运行。

如果您想有条件地匹配参数,请使用 Arg.Is<T>(Predicate<T> condition)

myBuilder
  .Build(Arg.Is<MyReferenceType>(_ => _.Property1 == "value1" && _.Property2 == "value2"))
  .Returns(expected);

只要传递的参数满足预期条件,行为应该与上面预期的相同。

引用NSubstitute: Argument matchers

关于c# - 根据对象的属性而不是其引用模拟设置返回类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49646167/

相关文章:

c# - 如何使静态类使用 C++ 引用字符串变量?

c# - 使用子字符串提取 YouTube 视频的视频 ID

javascript - 重新接线: How is it possible for this function to execute without returning the specified return value

ios - 你如何在 Swift 中编写模拟?

nunit - 最小起订量 4.0 : The type initializer for 'Moq.Mock` 1' threw an exception

c# - 循环遍历集合

c# - Windows服务/WCF和线程,初学者问题

php - 如何模拟内置的 php 套接字函数?

unit-testing - 使用 Authlogic on Rails 3 进行单元测试

c# - 单元测试以捕获 Controller 方法中的异常