N替代和团结 [英] NSubstitute and Unity
问题描述
我目前正在尝试学习DI&用Unity和NSubstitute模拟.我还使用了从以下问题中提取的自动模拟扩展程序:这是可以使用Unity(代替温莎城堡)吗?
I am currently trying to learn DI & Mocking, with Unity and NSubstitute. I am also using an automocking extension taken from this question: Is this possible with Unity (Instead of Castle Windsor)?
在下面的单元测试中,我试图通过我的方法Add()将NSubstitute返回值设置为10.但是,当通过控制器调用进行调试时,分配的值是默认值0,而不是预期的10.代理似乎没有拦截方法调用.
In my unit test below I am trying to set an NSubstitute return value of 10 from my method Add(). However when debugging through the controller call the assigned value is the default 0 rather than the expected 10. The proxy does not seem to be intercepting the method call.
我怀疑这是由于未正确注册我的类型/容器而导致的,任何人都可以将我指向正确的方向?
I suspect this is caused by not registering my Types/container correctly, anybody able to point me in the right direction?
[TestFixture]
public class ApplicationControllerTests
{
private IUnityContainer _container;
private ApplicationController _controller;
private ISampleService _sampleService;
[SetUp]
public void SetUp()
{
_container = new UnityContainer().AddExtension(new AutoMockingContainerExtension());
_controller = _container.Resolve<ApplicationController>();
_sampleService = _container.Resolve<ISampleService>();
}
[Test]
public void TestSampleService()
{
// This line is not working
_sampleService.Add(Arg.Any<int>(), Arg.Any<int>()).Returns(10);
var result = _controller.Index();
_sampleService.Received().Add(Arg.Any<int>(), Arg.Any<int>());
}
}
public class AutoMockingContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
var strategy = new AutoMockingBuilderStrategy(Container);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
class AutoMockingBuilderStrategy : BuilderStrategy
{
private readonly IUnityContainer _container;
public AutoMockingBuilderStrategy(IUnityContainer container)
{
_container = container;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = context.OriginalBuildKey;
if (key.Type.IsInterface && !_container.IsRegistered(key.Type))
context.Existing = CreateSubstitute(key.Type);
}
private static object CreateSubstitute(Type type)
{
return Substitute.For(new[] { type }, null);
}
}
}
还有我的控制器代码
public class ApplicationController : BaseController
{
private readonly ISampleService _sampleService;
public ApplicationController(ISampleService sampleService)
{
_sampleService = sampleService;
}
public ActionResult Index()
{
var result = _sampleService.Add(2, 3);
// result is 0, expected 10 ??
return View();
}
}
public interface ISampleService
{
int Add(int first, int second);
}
public class SampleService : ISampleService
{
public int Add(int first, int second)
{
return first + second;
}
}
推荐答案
实际上,Tormod是正确的问题是,当有人请求ISampleService
时,AutoMockingBuilderStrategy
每次都会返回不同的模拟实例.形成容器.
Actually Tormod is right the problem is that the AutoMockingBuilderStrategy
returns a different mock instance every time when somebody requests an ISampleService
form the container.
所以我的原始实现中有一个错误,即AutoMockingBuilderStrategy
不存储创建的模拟:
So there is a bug in my original implementation namely the AutoMockingBuilderStrategy
doesn't store the created mocks:
这是固定版本:
public class AutoMockingContainerExtension : UnityContainerExtension
{
protected override void Initialize()
{
var strategy = new AutoMockingBuilderStrategy(Container);
Context.Strategies.Add(strategy, UnityBuildStage.PreCreation);
}
class AutoMockingBuilderStrategy : BuilderStrategy
{
private readonly IUnityContainer container;
private readonly Dictionary<Type, object> substitutes
= new Dictionary<Type, object>();
public AutoMockingBuilderStrategy(IUnityContainer container)
{
this.container = container;
}
public override void PreBuildUp(IBuilderContext context)
{
var key = context.OriginalBuildKey;
if (key.Type.IsInterface && !container.IsRegistered(key.Type))
{
context.Existing = GetOrCreateSubstitute(key.Type);
context.BuildComplete = true;
}
}
private object GetOrCreateSubstitute(Type type)
{
if (substitutes.ContainsKey(type))
return substitutes[type];
var substitute = Substitute.For(new[] {type}, null);
substitutes.Add(type, substitute);
return substitute;
}
}
}
这篇关于N替代和团结的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!