使用AutoNSubstituteData xUnit和AutoFixture在测试中创建控制器

时间:2014-10-27 06:47:42

标签: xunit.net autofixture nsubstitute asp.net-mvc-5.2

我不相信这种模式,但我正在尝试创建一个这样的测试: 我想创建Controller,但将依赖项作为Frozen参数提供给测试。

测试如下。

    [Theory, AutoNSubstituteData]
    public void TestService(
           [Frozen] ITestService service, 
           TestController controller, 
           string value)
    {
        controller.Test(value);
        service.Received().ProcessValue(Arg.Any<string>());
    }

我在测试开始时收到此错误。

    System.InvalidOperationExceptionAn exception was thrown 
    while getting data for theory WebTest.Tests.Controllers.TestControllerRouteTests
    .TestService:
    System.Reflection.TargetInvocationException: 
    Exception has been thrown by the target of an invocation. ---> System.NotImplementedException:     The method or operation is not implemented.
       at System.Web.HttpContextBase.get_Items()
       at System.Web.WebPages.DisplayModeProvider.SetDisplayMode(HttpContextBase context, IDisplayMode displayMode)

我已从此AutoNSubsituteData帖子中创建了AutoNSubstituteData属性。 我试图创建一个假上下文来解决问题。

/// <summary>
/// The auto n substitute data attribute.
/// </summary>
internal class AutoNSubstituteDataAttribute : AutoDataAttribute
{
    /// <summary>
    /// Initialises a new instance of the <see cref="AutoNSubstituteDataAttribute"/> class.
    /// </summary>
    internal AutoNSubstituteDataAttribute()
        : base(new Fixture()
        .Customize(new AutoNSubstituteCustomization())
        .Customize(new HttpContextBaseCustomization()))
    {
    }
}

internal class HttpContextBaseCustomization : ICustomization
{
    public void Customize(IFixture fixture)
    {
        fixture.Customize<ViewContext>(_ => _.OmitAutoProperties());
        fixture.Customize<HttpContextBase>(_ => _.FromFactory(() => Substitute.For<HttpContextBase>()));
    }
}

2 个答案:

答案 0 :(得分:5)

这里的问题实际上是HttpContextBase.Items 邪恶,因为 NotImplementedException

通常,模拟库默认情况下会覆盖虚拟成员,我怀疑NSubstitute也是如此。如果这是正确的,一个选项是将Test Double配置为覆盖Items属性。

另一个选择是要求AutoFixture省略Controller中的HttpContext属性,如果你在测试用例中不需要它。

答案 1 :(得分:1)

one of the posts linked to by Mark Seemann,我们发现以下代码段为我们解决了问题 -

fixture.Customize<ControllerContext>(c => c
            .Without(x => x.DisplayMode));