我可以让NSubstitute自动模拟我的具体类吗?

我可以让NSubstitute自动模拟我的具体类吗?,nsubstitute,Nsubstitute,我有一个用“NSubstitute”模拟的接口,它包含返回concreate类的属性,即返回值不是接口。e、 g public interface ISomething { SomeObj First { get; } SomeObj Second { get; } } “SomeObj”具体类具有默认构造函数,但“NSubstitute”始终为这些属性返回“null”。类本身不在我的控制之下,因此我不能简单地使它从接口派生 “NSubstitute”能否模拟这些类型的属性?或

我有一个用“NSubstitute”模拟的接口,它包含返回concreate类的属性,即返回值不是接口。e、 g

public interface ISomething
{
    SomeObj First { get; }
    SomeObj Second { get; }
}
“SomeObj”具体类具有默认构造函数,但“NSubstitute”始终为这些属性返回“null”。类本身不在我的控制之下,因此我不能简单地使它从接口派生

“NSubstitute”能否模拟这些类型的属性?或者有没有一种方法可以推翻这种行为?否则,我必须在测试之前手动初始化mock,这可能需要大量代码(即使通过公共方法重用)


也许有一个更简单的解决方案,我已经看过了?

如果类有一个默认(无参数)构造函数,并且其所有成员都是虚拟的,那么类将被自动模拟(请参见的简介中的注释)。这样做的目的是,如果我们正在使用一个替代品,突然发现一个非虚拟的、未经修改的代码路径,在一个我们认为是假的实例中做了不好的事情,那么我们就可以减少潜在的不必要的(破坏性的?)副作用

NSubstitute无法覆盖此行为。相反,我建议您通过自己的工厂方法(例如,测试项目中的static
Sub.For(…)
方法)创建所有替换,该方法使用NSubstitute生成替换,然后应用您需要的所有特定初始化规则,比如使用反射来为每个类属性剔除值

希望这有帮助

可能的相关链接:
  • 我建议你试着去做

这不算作自动模拟,但您也问了“或者有没有办法覆盖该行为?”和“也许有一个更简单的解决方案,我已经看过了?”

这个答案取决于你问题中的陈述,即:

  • SomeObj
    是一个不受您控制的类,我假设它是单独测试的,或者是不可测试的
  • SomeObj
    有一个默认构造函数
当然,它要求您“在测试之前手动初始化mock”,但是由于您没有告诉我们这个对象是什么,所以不可能知道完全实现它需要多少工作

公共类SomeObj
{
//非虚拟以防止自动模拟
public void Dummy(){}
}
公共接口
{
SomeObj First{get;}
SomeObj第二个{get;}
}
[测试方法]
公共无效测试--U 17182355ms()
{
ISomething mockedSomething=替换.For();
SomeObj firstObj=模仿某物;
Assert.IsNull(firstObj);
mockedsothing.First.Returns(newsomeobj());
mockedsothing.Second.Returns(newsomeobj());
firstObj=模仿某物。首先;
Assert.IsNotNull(firstObj);
}
另一种方法虽然也有其自身的缺点,但可以为
SomeObj
提取您自己的接口,如下所示:

公共接口对象
{
void Dummy();
}
公共类MySomeObj:SomeObj,isomobj
{
}

然后在测试中模拟
isomobj

是的,似乎并不是所有具体类的成员都是虚拟的。似乎对替换进行反思可能是最好的解决方案。我不久前写了一个反思示例,如果这有助于作为起点:(我更新了我的答案以包含此链接)Thx,在我的情况下,我想扩展它来处理间接属性,即返回具体类的接口的属性。是一个选项,如果您愿意包含一个内部无参数构造函数。老实说,我发现作为一个规则,几乎这样做是合理的。Nsubstitute与AutoFixture相结合应该能够做到这一点。