gpt4 book ai didi

c# - 在使用 nSubstitute 和 Autofixture 作为 DI 容器的单元测试中,如何获取模拟对象?

转载 作者:行者123 更新时间:2023-12-05 03:07:45 30 4
gpt4 key购买 nike

我以前在单元测试中使用 Moq 和 AutoMoqer,但我的团队已决定改为使用 NSubstitute。我们大量使用 DI,所以我希望能够请求一个目标进行测试,并让该目标自动将所有模拟对象提供给其构造函数,或者换句话说,一个传递模拟的 DI 容器。我还想根据需要修改那些模拟对象。

使用 Moq/AutoMoq/MSTest 的示例

[TestMethod]
public void ReturnSomeMethod_WithDependenciesInjectedAndD1Configured_ReturnsConfiguredValue()
{
const int expected = 3;
var diContainer = new AutoMoq.AutoMoqer();

var mockedObj = diContainer.GetMock<IDependency1>();
mockedObj
.Setup(mock => mock.SomeMethod())
.Returns(expected);

var target = diContainer.Resolve<MyClass>();
int actual = target.ReturnSomeMethod();

Assert.AreEqual(actual, expected);
}

public interface IDependency1
{
int SomeMethod();
}

public interface IDependency2
{
int NotUsedInOurExample();
}

public class MyClass
{
private readonly IDependency1 _d1;
private readonly IDependency2 _d2;

//please imagine this has a bunch of dependencies, not just two
public MyClass(IDependency1 d1, IDependency2 d2)
{
_d1 = d1;
_d2 = d2;
}

public int ReturnSomeMethod()
{
return _d1.SomeMethod();
}
}

由于我的问题措辞不当,而且我进行了更多研究,因此我找到了一种使用 NSubstitute/AutofacContrib.NSubstitute/XUnit 使其正常工作的方法:

[Fact]
public void ReturnSomeMethod_WithDependenciesInjectedAndD1Configured_ReturnsConfiguredValue()
{
const int expected = 3;
var autoSubstitute = new AutoSubstitute();
autoSubstitute.Resolve<IDependency1>().SomeMethod().Returns(expected);

var target = autoSubstitute.Resolve<MyClass>();
int actual = target.ReturnSomeMethod();

Assert.Equal(actual, expected);
}

public interface IDependency1
{
int SomeMethod();
}

public interface IDependency2
{
int NotUsedInOurExample();
}

public class MyClass
{
private readonly IDependency1 _d1;
private readonly IDependency2 _d2;

//please imagine this has a bunch of dependencies, not just two
public MyClass(IDependency1 d1, IDependency2 d2)
{
_d1 = d1;
_d2 = d2;
}

public int ReturnSomeMethod()
{
return _d1.SomeMethod();
}
}

我仍然有我原来的问题。我如何使用 AutoFixture.AutoNSubstitute 作为 DI 容器来做到这一点?

最佳答案

您可以将 AutoFixture 变成 Auto-Mocking Container具有各种动态模拟库,包括 NSubstitute。

重写 OP 测试就这么简单:

[Fact]
public void ReturnSomeMethod_UsingAutoFixtureAutoNSubstitute()
{
const int expected = 3;
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Freeze<IDependency1>().SomeMethod().Returns(expected);

var target = fixture.Create<MyClass>();
var actual = target.ReturnSomeMethod();

Assert.Equal(actual, expected);
}

在这里,我使用了 xUnit.net而不是 MSTest,但翻译它应该是微不足道的。

这里的关键是 Freeze 方法,它实质上将类型参数的生命周期从 transient 更改为 singleton。这意味着在调用 Freeze 之后,所有其他时间特定的 Fixture 实例必须创建一个 IDependency 对象,它将重用该对象它卡住了。

Freeze 还返回它刚刚卡住的对象,这使您可以轻松地在其中“点”入 - 在本例中使用 NSubstitute 的 API。

关于c# - 在使用 nSubstitute 和 Autofixture 作为 DI 容器的单元测试中,如何获取模拟对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46596161/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com