简体   繁体   中英

creating controller in a test using AutoNSubstituteData xUnit and AutoFixture

I am not convinced about the pattern, but I am trying to create a test like this: I want to create the Controller, but have the dependencies available as Frozen parameters to the test.

The test is as follows.

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

I get this error as the test starts.

    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)

I have created the AutoNSubstituteData attribute from this AutoNSubsituteData post. I have attempted to create a fake context to solve the problem.

/// <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>()));
    }
}

The problem here is really that HttpContextBase.Items is evil , because it's a virtual property that always throws a NotImplementedException .

Usually, mock libraries tend not to override virtual members by default, and I suspect that this is also the case for NSubstitute. If this is correct, one option would be to configure the Test Double to override the Items property.

Another option is to ask AutoFixture to omit the HttpContext property from the Controller, if you don't need it in your test case.

From one of the posts linked to by Mark Seemann , we found the following snippet solve the issue for us-

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM