I have the following code in my class under testing:
devices = ContainerLocator.Container.Resolve<IDevicesList>(); [1]
In test method I'm trying to write:
var fakeDeviceList = Substitute.For<IDevicesList>();
Substitute.For<IContainerProvider>().Resolve<IDevicesList>().Returns(fakeDeviceList);
but I got a null reference exception for ContainerLocator.Container in line [1].
I tried to use
var provider = Substitute.For<IContainerProvider>();
ContainerLocator.Container.Returns(provider);
provider.Resolve<IDevicesList>().Returns(fakeDeviceList);
but got an exception during test run:
Message:
NSubstitute.Exceptions.CouldNotSetReturnDueToNoLastCallException : Could not find a call to return from.
So my question is how could I make a substitution for ContainerLocator.Container? Thank you in advance.
uj5u.com熱心網友回復:
I have the following code in my class under testing:
devices = ContainerLocator.Container.Resolve<IDevicesList>();
That's the reason why you don't inject the container. In fact, you avoid using the container at all except during the registration phase and the initial call to Resolve.
What you should do, is to let the container do the resolving work by injecting what you actually want, not the almighty container.
internal class MyService
{
public MyService( IDeviceList devices )
{
}
}
or
internal class MyService
{
public MyService( IEnumerable<IDevice> devices )
{
}
}
or
internal class MyService
{
public MyService( Lazy<IEnumerable<IDevice>> devices )
{
}
}
or
internal class MyService
{
public MyService( IEnumerable<Lazy<IDevice>> devices )
{
}
}
The differences between injecting a Lazy<IEnumerable> and a IEnumerable<Lazy> are subtle and depend on the actual container used, the behavior of the IContainerProvider is undefined in general in this case.
Anyway, you can easily inject the mocked devices in this way without having to mock the container or even use the real container during testing.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/355045.html
標籤:c# unit-testing prism nunit-3.0
上一篇:React函式被多次呼叫(每秒)
