如何在 NUnit 中替换 Prism ContainerLocator.Container

How to substitute Prism ContainerLocator.Container in NUnit

我的 class 测试中有以下代码:

  devices = ContainerLocator.Container.Resolve<IDevicesList>();           [1]

在我试图写的测试方法中:

 var fakeDeviceList = Substitute.For<IDevicesList>();
 Substitute.For<IContainerProvider>().Resolve<IDevicesList>().Returns(fakeDeviceList);

但是我在行 [1] 中得到了 ContainerLocator.Container 的空引用异常。 我尝试使用

var provider = Substitute.For<IContainerProvider>();
ContainerLocator.Container.Returns(provider);
provider.Resolve<IDevicesList>().Returns(fakeDeviceList);

但在测试期间出现异常 运行:

Message: 
NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException : Could not find a call to return from.

所以我的问题是如何替换 ContainerLocator.Container?提前谢谢你。

I have the following code in my class under testing:

devices = ContainerLocator.Container.Resolve<IDevicesList>();

这就是你不注入容器的原因。事实上,除了在注册阶段和对 Resolve.

的初始调用之外,您完全 避免使用容器

So my question is how could I make a substitution for ContainerLocator.Container?

答案是:你不知道

应该做的是让容器通过注入你真正想要的而不是万能的容器来完成解析工作。

internal class MyService
{
    public MyService( IDeviceList devices )
    {
    }
}

internal class MyService
{
    public MyService( IEnumerable<IDevice> devices )
    {
    }
}

internal class MyService
{
    public MyService( Lazy<IEnumerable<IDevice>> devices )
    {
    }
}

internal class MyService
{
    public MyService( IEnumerable<Lazy<IDevice>> devices )
    {
    }
}

注入 Lazy<IEnumerable>IEnumerable<Lazy> 之间的区别很微妙,取决于实际使用的容器,在这种情况下 IContainerProvider 的行为通常是未定义的。

无论如何,您可以通过这种方式轻松注入模拟设备,而无需模拟容器甚至在测试期间使用真实容器。