Skip to content

Working with Headers

We really didn't worry much about HTTP niceties when I started web programming in the late 90's, but you can no longer get away with that in today's world. To more correctly use HTTP, Alba comes with some helpers to deal with HTTP header values.

Setting Request Headers

To set request headers, you can directly write against the HttpContext.Request.Headers collection:

cs
public async Task setting_request_headers(IAlbaHost system)
{
    await system.Scenario(_ =>
    {
        _.WithRequestHeader("foo", "bar");
        
    });
}
public async Task setting_request_headers(IAlbaHost system)
{
    await system.Scenario(_ =>
    {
        _.WithRequestHeader("foo", "bar");
        
    });
}

snippet source | anchor

There are also some specific helpers for very common content negotiation-related headers:

cs
public async Task conneg_helpers(IAlbaHost system)
{
    await system.Scenario(_ =>
    {
        // Set the accepts header on the request
        _.Get.Url("/").Accepts("text/plain");

        // Specify the etag header value
        _.Get.Url("/").Etag("12345");

        // Set the content-type header on the request
        _.Post.Url("/").ContentType("text/json");

        // This is a superset of the code above that
        // will set the content-type header as well
        _.Post.Json(new InputModel()).ToUrl("/");
    });
}
public async Task conneg_helpers(IAlbaHost system)
{
    await system.Scenario(_ =>
    {
        // Set the accepts header on the request
        _.Get.Url("/").Accepts("text/plain");

        // Specify the etag header value
        _.Get.Url("/").Etag("12345");

        // Set the content-type header on the request
        _.Post.Url("/").ContentType("text/json");

        // This is a superset of the code above that
        // will set the content-type header as well
        _.Post.Json(new InputModel()).ToUrl("/");
    });
}

snippet source | anchor

Do add extension methods off of the Alba Scenario class for common operations in your tests to remove some of the tedium.

Asserting on Expected Response Headers

Alba comes with some out of the box assertions to declaratively check expected header values:

cs
public async Task asserting_on_header_values(IAlbaHost system)
{
    await system.Scenario(_ =>
    {
        // Assert that there is one and only one value equal to "150"
        _.Header(HeaderNames.ContentLength).SingleValueShouldEqual("150");

        // Assert that there is no value for this response header
        _.Header(HeaderNames.Connection).ShouldNotBeWritten();

        // Only write one value for this header
        _.Header(HeaderNames.SetCookie).ShouldHaveOneNonNullValue();

        // Assert that the header has any values
        _.Header(HeaderNames.ETag).ShouldHaveValues();

        // Assert that the header has the given values
        _.Header(HeaderNames.WWWAuthenticate).ShouldHaveValues("NTLM", "Negotiate");

        // Assert that the header matches a regular expression
        _.Header(HeaderNames.Location).SingleValueShouldMatch(new Regex(@"^/items/\d*$"));

        // Check the content-type header
        _.ContentTypeShouldBe("text/json");
    });
}
public async Task asserting_on_header_values(IAlbaHost system)
{
    await system.Scenario(_ =>
    {
        // Assert that there is one and only one value equal to "150"
        _.Header(HeaderNames.ContentLength).SingleValueShouldEqual("150");

        // Assert that there is no value for this response header
        _.Header(HeaderNames.Connection).ShouldNotBeWritten();

        // Only write one value for this header
        _.Header(HeaderNames.SetCookie).ShouldHaveOneNonNullValue();

        // Assert that the header has any values
        _.Header(HeaderNames.ETag).ShouldHaveValues();

        // Assert that the header has the given values
        _.Header(HeaderNames.WWWAuthenticate).ShouldHaveValues("NTLM", "Negotiate");

        // Assert that the header matches a regular expression
        _.Header(HeaderNames.Location).SingleValueShouldMatch(new Regex(@"^/items/\d*$"));

        // Check the content-type header
        _.ContentTypeShouldBe("text/json");
    });
}

snippet source | anchor

You do also have the ability to just interrogate the HttpContext.Response in your unit test methods for anything not covered in the helpers above.