如何在 NUnit 中替换 Prism ContainerLocator.Container
Posted
技术标签:
【中文标题】如何在 NUnit 中替换 Prism ContainerLocator.Container【英文标题】:How to substitute Prism ContainerLocator.Container in NUnit 【发布时间】:2021-12-22 22:15:44 【问题描述】:我在测试中的班级中有以下代码:
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
?提前谢谢你。
【问题讨论】:
【参考方案1】:我在测试中的班级中有以下代码:
devices = ContainerLocator.Container.Resolve<IDevicesList>();
这就是你不注入容器的原因。事实上,除了在注册阶段和对Resolve
的初始调用之外,您完全避免使用容器。
所以我的问题是如何替换
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
的行为通常是未定义的。
无论如何,您可以通过这种方式轻松注入模拟设备,而无需在测试期间模拟容器甚至使用真实容器。
【讨论】:
以上是关于如何在 NUnit 中替换 Prism ContainerLocator.Container的主要内容,如果未能解决你的问题,请参考以下文章