Mocking IHttpContextAccessor

The IHttpContextAccessor Interface Provides access to the current HttpContext, if one is available.

Example code to test

A common usage is a correlation id which is a unique identifier thats attached to requests/messages across distributed systems to reference to a particular transaction or event chain.

Note that IHttpContextAccessor httpContextAccessor would have been inject by the framework.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
public Guid GetCorrelationId()
{
var correlationId = _httpContextAccessor // defensive coding could also be added to check for the existance of _httpContextAccessor
.HttpContext
.Request
.Headers.FirstOrDefault(header =>
header.Key.Equals(
"My-Cool-Correlation-Id",
StringComparison.InvariantCultureIgnoreCase))
.Value
.ToString();

if (Guid.TryParse(correlationId, out var parsedValue))
{
return parsedValue;
}

return Guid.NewGuid(); // Create new if one was not present
}

Example unit test

The key is to simply mock out the chain one node at a time so the test is easy to read - you can do this in one .Setup but it will be harder to read/maintain.

The ticky bit is to use new HeaderDictionary(new Dictionary<string, StringValues> for the headers, its a dictionary of dictionaries \ :D /

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
[Fact]
public void GetCorrelationId_WhenHeaderContainsCorrelationId_ReturnIt()
{
// Arrange
var expected = Guid.NewGuid();
var headers = new HeaderDictionary(new Dictionary<string, StringValues>
{
{
"My-Cool-Correlation-Id",
expected.ToString()
}
});

var httpRequestMock = new Mock<HttpRequest>();
var httpContextAccessorMock = new Mock<IHttpContextAccessor>();

httpRequestMock
.Setup(x => x.Headers)
.Returns(headers);

httpContextAccessorMock
.Setup(a => a.HttpContext.Request)
.Returns(httpRequestMock.Object);

var classUnderTest = new MyRequestContext(httpContextAccessorMock.Object);

// Act
var actual = classUnderTest.GetCorrelationId();

// Assert
actual.Should().Be(expected);
}

References