Mock IHttpContextAccessor in Unit Tests

前端 未结 2 1256
情深已故
情深已故 2021-01-01 09:01

I have a method to get header value using IHttpContextAccessor

public class HeaderConfiguration : IHeaderConfiguration
{
    public HeaderConfig         


        
相关标签:
2条回答
  • 2021-01-01 09:34

    You can use the DefaultHttpContext as a backing for the IHttpContextAccessor.HttpContext. Saves you having to set-up too many things

    Next you cannot use It.IsAny<string>() as a Returns result. They were meant to be used in the set up expressions alone.

    Check the refactor

    [Fact]
    public async Task test_GetBookByBookId() {
        //Arrange
    
        //Mock IHttpContextAccessor
        var mockHttpContextAccessor = new Mock<IHttpContextAccessor>();
        var context = new DefaultHttpContext();
        var fakeTenantId = "abcd";
        context.Request.Headers["Tenant-ID"] = fakeTenantId;
        mockHttpContextAccessor.Setup(_ => _.HttpContext).Returns(context);
        //Mock HeaderConfiguration
        var mockHeaderConfiguration = new Mock<IHeaderConfiguration>();
        mockHeaderConfiguration
            .Setup(_ => _.GetTenantId(It.IsAny<IHttpContextAccessor>()))
            .Returns(fakeTenantId);
    
        var book = new Book(mockHttpContextAccessor.Object, mockHeaderConfiguration.Object);
    
        var bookId = "100";
    
        //Act
        var result = await book.GetBookByBookId(bookId);
    
        //Assert
        result.Should().NotBeNull().And.
            BeOfType<List<BookModel>>();
    }
    

    There may also be an issue with the Class Under Test as it is manually initializing the HeaderConfiguration when it should actually be explicitly injected.

    public Book(IHeaderConfiguration headerConfiguration, IHttpContextAccessor httpContextAccessor) {
        _httpContextAccessor = httpContextAccessor;
        _tenantID = headerConfiguration.GetTenantId(_httpContextAccessor);
    }
    
    0 讨论(0)
  • 2021-01-01 09:50

    In my scenario I had to mock IHttpContextAccessor and access the inner request url bits.
    I'm sharing it here because I spent a decent amount of time figuring this out and hopefully it'll help someone.

    readonly Mock<IHttpContextAccessor> _HttpContextAccessor = 
      new Mock<IHttpContextAccessor>(MockBehavior.Strict);
    
    void SetupHttpContextAccessorWithUrl(string currentUrl)
    {
      var httpContext = new DefaultHttpContext();
      setRequestUrl(httpContext.Request, currentUrl);
    
      _HttpContextAccessor
        .SetupGet(accessor => accessor.HttpContext)
        .Returns(httpContext);
    
      static void setRequestUrl(HttpRequest httpRequest, string url)
      {
        UriHelper
          .FromAbsolute(url, out var scheme, out var host, out var path, out var query, 
            fragment: out var _);
    
        httpRequest.Scheme = scheme;
        httpRequest.Host = host;
        httpRequest.Path = path;
        httpRequest.QueryString = query;
      }
    }
    
    0 讨论(0)
提交回复
热议问题