locked
Testing filters with IDependencyScope in Web API RRS feed

  • Question

  • User2082812578 posted

    I have WebApi simple NUnit Test

    [Test]
    public async Task Test()
    {
    var attribute = new TestAuthenticationAttribute {ApiVersions = new[] {"v1"}};
    System.Web.Http.Controllers.HttpActionContext context = CreateExecutingContext();
    
    var executedContext = new HttpAuthenticationContext(context, null);
    
    const string reasonPhrase = "ReasonPhrase";
    const string messagePhrase = "MessagePhrase";
    
    executedContext.ErrorResult = new AuthenticationFailureResult(reasonPhrase, messagePhrase, executedContext.Request);
    
    await attribute.AuthenticateAsync(executedContext, CancellationToken.None);
    
    var errorResult = await executedContext.ErrorResult.ExecuteAsync(new CancellationToken());
    
    Assert.AreEqual(HttpStatusCode.Unauthorized, errorResult.StatusCode);
    }
    
    private System.Web.Http.Controllers.HttpActionContext CreateExecutingContext()
    {
    return new System.Web.Http.Controllers.HttpActionContext { ControllerContext = new HttpControllerContext {Request = new HttpRequestMessage()
    {
    RequestUri = new Uri("http://TestApi/api/v1/Test")
    }}};
    }

    and in TestAuthenticationAttribute I have

    if (context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is IExternalService externalService)
    Do some actions;

    How to set/resolve IExternalService dependency in test? Do I need e.g. UnityContainer or I can do it without container?

    Monday, November 13, 2017 4:31 PM

Answers

  • User1120430333 posted

    context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is IExternalService externalService is example from "ASP.NET Web API 2 Recipes" book 277 page

    IExternalService should be mocked out using a mocking framework,  which means that you would have to know the class/object that implements IExternalService and what it is doing internally.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 13, 2017 10:24 PM
  • User2082812578 posted

    I added HttpConfiguration to my HttpActionContext and now context.Request.GetDependencyScope() doesn't throw System.NullReferenceException. Of cource context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is null, but now It's ok for my tests. 

            private System.Web.Http.Controllers.HttpActionContext CreateExecutingContext()
            {
                var config = new HttpConfiguration();
    
                var httpActionContext =  new System.Web.Http.Controllers.HttpActionContext
                {
                    ControllerContext = new HttpControllerContext
                    {
                        Request = new HttpRequestMessage()
                        {
                            RequestUri = new Uri("http://TestApi/api/v1/Test"),
                        },
                        
                        Configuration = config
                    }
                };
    
                httpActionContext.ControllerContext.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;
    
                return httpActionContext;
    
            }

    If I want to resolve dependency, I will can add DependencyResolver to my config or Mocking framework

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 14, 2017 6:37 AM

All replies

  • User1120430333 posted

    http://www.artima.com/weblogs/viewpost.jsp?thread=126923

    What are you trying to do a unit test or an integration test? if you are trying to do a unit test, then nothing you doing is deemed to be a unit test.

    if (context.Request.GetDependencyScope().GetService(typeof(new ExternalService)) is IExternalService externalService)

    the above is how you could resolve the dependency. The IoC will not work, as the IoC has to be used in what is going to  use the IoC, the unit of code, and you test that unit of code that is actually going to use the object instanced in the IoC container.

    Monday, November 13, 2017 6:05 PM
  • User2082812578 posted

    I try to do unit test.

    I have authentication filter and it works because I have unity container in my host and context.Request.GetDependencyScope().GetService(typeof(IExternalService)) works. Example https://docs.microsoft.com/en-us/aspnet/web-api/overview/security/authentication-filters

    public class MyCustomAuthenticationAttribute : Attribute, IAuthenticationFilter
    {
    	public async Task AuthenticateAsync(HttpAuthenticationContext context, CancellationToken cancellationToken)
    	{
      		HttpRequestMessage request = context.Request;
        		AuthenticationHeaderValue authorization = request.Headers.Authorization;
    
        		//If there are no credentials, do nothing.
        		if (authorization == null)
        		{
            		return;
        		}
    
    		..................
    
    		if (context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is IExternalService externalService)
    			externalService.DoJob();
    
    		..................
    	}
    }

    Then I want to do Unit test as I wrote. It's expect result, because test doesn't resolve IExternalService. I want to do like this

    public class ExternalServiceStub: IExternalService
    {
    	public void DoJob()
    	{
    		do something;
    	}
    }

    context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is IExternalService externalService is example from "ASP.NET Web API 2 Recipes" book 277 page

    Monday, November 13, 2017 7:43 PM
  • User1120430333 posted

    context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is IExternalService externalService is example from "ASP.NET Web API 2 Recipes" book 277 page

    IExternalService should be mocked out using a mocking framework,  which means that you would have to know the class/object that implements IExternalService and what it is doing internally.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, November 13, 2017 10:24 PM
  • User2082812578 posted

    I added HttpConfiguration to my HttpActionContext and now context.Request.GetDependencyScope() doesn't throw System.NullReferenceException. Of cource context.Request.GetDependencyScope().GetService(typeof(IExternalService)) is null, but now It's ok for my tests. 

            private System.Web.Http.Controllers.HttpActionContext CreateExecutingContext()
            {
                var config = new HttpConfiguration();
    
                var httpActionContext =  new System.Web.Http.Controllers.HttpActionContext
                {
                    ControllerContext = new HttpControllerContext
                    {
                        Request = new HttpRequestMessage()
                        {
                            RequestUri = new Uri("http://TestApi/api/v1/Test"),
                        },
                        
                        Configuration = config
                    }
                };
    
                httpActionContext.ControllerContext.Request.Properties[HttpPropertyKeys.HttpConfigurationKey] = config;
    
                return httpActionContext;
    
            }

    If I want to resolve dependency, I will can add DependencyResolver to my config or Mocking framework

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Tuesday, November 14, 2017 6:37 AM