Skip to content

Writing Custom Assertions

TIP

All of the assertions are applied during the Scenario execution, and any failures will be reported out in the Exception message thrown by Alba on Scenario failures.

The Scenario assertions in Alba are completely extensible and you can happily add your own via extension methods - but please send anything that's generally useful as a pull request to Alba itself;-)

The first step is to write your own implementation of this interface:

cs
public interface IScenarioAssertion
{
    void Assert(Scenario scenario, HttpContext context, ScenarioAssertionException ex);
}
public interface IScenarioAssertion
{
    void Assert(Scenario scenario, HttpContext context, ScenarioAssertionException ex);
}

snippet source | anchor

As an example, here's the assertion from Alba that validates that the response body is supposed to

cs
internal class BodyContainsAssertion : IScenarioAssertion
{
    public string Text { get; set; }

    public BodyContainsAssertion(string text)
    {
        Text = text;
    }

    public void Assert(Scenario scenario, HttpContext context, ScenarioAssertionException ex)
    {
        var body = ex.ReadBody(context);
        if (!body.Contains(Text))
        {
            // Add the failure message to the exception. This exception only
            // gets thrown if there are failures.
            ex.Add($"Expected text '{Text}' was not found in the response body");
        }
    }
}
internal class BodyContainsAssertion : IScenarioAssertion
{
    public string Text { get; set; }

    public BodyContainsAssertion(string text)
    {
        Text = text;
    }

    public void Assert(Scenario scenario, HttpContext context, ScenarioAssertionException ex)
    {
        var body = ex.ReadBody(context);
        if (!body.Contains(Text))
        {
            // Add the failure message to the exception. This exception only
            // gets thrown if there are failures.
            ex.Add($"Expected text '{Text}' was not found in the response body");
        }
    }
}

snippet source | anchor

Once you have your assertion class, you can apply it to a scenario through an extension method against the Scenario class. Here's the Scenario.ContentShouldContain(text) implementation from Alba itself:

cs
/// <summary>
/// Assert that the Http response contains the designated text
/// </summary>
/// <param name="scenario"></param>
/// <param name="text"></param>
/// <returns></returns>
public static Scenario ContentShouldContain(this Scenario scenario, string text)
{
    return scenario.AssertThat(new BodyContainsAssertion(text));
}
/// <summary>
/// Assert that the Http response contains the designated text
/// </summary>
/// <param name="scenario"></param>
/// <param name="text"></param>
/// <returns></returns>
public static Scenario ContentShouldContain(this Scenario scenario, string text)
{
    return scenario.AssertThat(new BodyContainsAssertion(text));
}

snippet source | anchor

Finally, use your new assertion in a Scenario like this:

cs
[Fact]
public Task using_scenario_with_ContentShouldContain_declaration_happy_path()
{
    router.Handlers["/one"] = c =>
    {
        c.Response.Write("**just the marker**");
        return Task.CompletedTask;
    };

    return host.Scenario(x =>
    {
        x.Get.Url("/one");
        x.ContentShouldContain("just the marker");
    });
}
[Fact]
public Task using_scenario_with_ContentShouldContain_declaration_happy_path()
{
    router.Handlers["/one"] = c =>
    {
        c.Response.Write("**just the marker**");
        return Task.CompletedTask;
    };

    return host.Scenario(x =>
    {
        x.Get.Url("/one");
        x.ContentShouldContain("just the marker");
    });
}

snippet source | anchor