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

Jim*_*Jim 3 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>());
    }
Run Code Online (Sandbox Code Playgroud)

测试开始时我收到此错误.

    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)
Run Code Online (Sandbox Code Playgroud)

我已经从这个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>()));
    }
}
Run Code Online (Sandbox Code Playgroud)

Mar*_*ann 5

这里的问题实际上是HttpContextBase.Items邪恶的,因为它是一个总是抛出一个虚拟属性.NotImplementedException

通常,模拟库默认情况下不会覆盖虚拟成员,我怀疑NSubstitute也是如此.如果这是正确的,一个选项是配置测试双重覆盖该Items属性.

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