私は現在、Unity と NSubstitute を使用して、DI とモッキングを学ぼうとしています。私はまた、この質問から取られた自動モック拡張機能を使用しています:これは Unity (Castle Windsor の代わりに) で可能ですか?
以下の単体テストでは、メソッド Add() から NSubstitute の戻り値 10 を設定しようとしています。ただし、コントローラー呼び出しを介してデバッグする場合、割り当てられた値は、予想される 10 ではなくデフォルトの 0 です。プロキシはメソッド呼び出しをインターセプトしていないようです。
これは、タイプ/コンテナを正しく登録していないことが原因であると思われます。誰かが私を正しい方向に向けることができますか?
[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;
}
}