c# - 替换部分模拟对象中的只读属性

标签 c# unit-testing mocking nsubstitute

我正在测试一个 MVC Controller ,它依赖于从基类的只读属性返回的值。

此属性的 getter 在被调用时抛出异常,因为它依赖于 HttpContext(和其他讨厌的东西),我宁愿避免模拟。

这是我到目前为止尝试过的:

controller = Substitute.ForPartsOf<MyController>(
    Substitute.For<SomeDependency>(),
);

controller.UserInfo.Returns(new UserInfo());

然而,一旦访问 UserInfo,就会抛出异常。

基类的属性是:

public UserInfo UserInfo
{
    get
    {
        // HttpContext dependent stuff
    }
}

我已尝试将基类属性设置为虚拟,但随后出现 CaSTLe 代理异常。

最佳答案

我想你可能遇到了另一个问题。 NSubstitute 能够处理虚拟属性的替换。这里有一个小程序可以说明

public class SubstitutedClass
{
    public virtual int SubstitutedProperty { get { throw new InvalidOperationException(); }  }
}

internal class Program
{
    private static void Main(string[] args)
    {
        var test2 = Substitute.For<SubstitutedClass>();
        test2.SubstitutedProperty.Returns(10);
        Console.WriteLine(test2.SubstitutedProperty);
    }
}

编辑: 关于您对 ForPartsOf 的使用,我认为不可能以这种方式覆盖属性,因为无法通知 NSubstitute 我们不这样做' 想让它调用基本代码。这就是为什么文档提到部分子是 not recommended

您可以更改基类以返回虚函数的值;然后将替换此虚函数。调用者没有签名更改。虽然这是一个 hack,但你会得到你需要的东西

public class SubstitutedClass
{
    public virtual int SubstitutedProperty { get { return InnerValue(); } }
    public virtual int InnerValue() { throw new InvalidOperationException(); }
}

var test2 = Substitute.ForPartsOf<SubstitutedClass>();
test2.When(t => t.InnerValue()).DoNotCallBase();
test2.InnerValue().Returns(10);

关于c# - 替换部分模拟对象中的只读属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22958698/

相关文章:

c# - ASP.NET C# session 变量丢失

c# - 最小起订量 - 无论使用的参数如何,都执行带有参数的验证方法

javascript - Angular Jasmine - 模拟服务(angularjs-rails-resource) - TypeError : object is not a function

php - 如何使用 PHPUnit 的模拟测试名为 "method()"的方法?

javascript - 为什么这个 QUnit RegExp 测试失败了?

php - 创建 PHPUnit 模拟模型使用默认数据库而不是 CakePHP 中的测试

javascript - 在将 Squire.js 与 RequireJS 和 Mocha 一起使用时,如何避免引入全局泄漏?

c# - 带有 32 位 VB6 COM 对象的 64 位 C#

c# - 检索 VARCHAR(MAX)

c# - 服务定位器和依赖注入(inject)