Skip to main content

Extending aweXpect

Nuget

This library will never be able to cope with all ideas and use cases. Therefore, it is possible to use the aweXpect.Core package and write your own extensions. This package aims to be more stable than the main aweXpect package, to reduce the risk of version conflicts between different extensions.

Keep your extensions trimmable and AOT compatible like aweXpect itself, as described in Native AOT for extensions.

PageTopics
Constraints and resultsconstraints, negation, result types, nested and asynchronous expectations
Message conventionshow the failure messages of an extension should read
Customization valuescustomization values of your own, with lifetimes
Initializationvalue formatters and test framework adapters
Native AOT for extensionsthe metadata your expectations need under Native AOT
Testing and packagingtesting an extension and referencing aweXpect.Core

Your first expectation​

The samples in this section use the following namespaces:

using System.Diagnostics.CodeAnalysis;
using aweXpect.Core;
using aweXpect.Results;

The samples on this and the following pages verify tracks of the following type, such as "Love Me Do" (2:22) or "Hey Jude" (7:11):

public record Track(string Title, TimeSpan Duration);

Expectations​

You can extend the expectations for any types, by adding extension methods on IThat<TType>.

If you want to verify that a Track is radio friendly, i.e. that it lasts at most three minutes, you specify the following method signature:

/// <summary>
/// Verifies that the <paramref name="subject"/> is radio friendly, i.e. that it lasts at most three minutes.
/// </summary>
public static AndOrResult<Track, IThat<Track?>> IsRadioFriendly(this IThat<Track?> subject)
{
// ...
}

The result type decides how the expectation can continue: AndOrResult allows combining it with further expectations using .And and .Or.

ExpectationBuilder​

The next step is to extract the ExpectationBuilder. In order to keep the automatic code suggestions for developers clear, IThat<TType> doesn't show it. The Get() extension method in the aweXpect.Core.Extending namespace gives access to it. This namespace holds the helpers for extension authors that extend types every user sees, so they only appear where you import it.

You can then use the ExpectationBuilder to add an IsRadioFriendlyConstraint:

using aweXpect.Core.Extending;

public static AndOrResult<Track, IThat<Track?>> IsRadioFriendly(this IThat<Track?> subject)
=> new(subject.Get().ExpectationBuilder.AddConstraint((it, grammars)
=> new IsRadioFriendlyConstraint(it, grammars)),
subject);

The factory receives the name of the subject (it) and the grammars of the sentence, which the constraint uses to write its part of the failure message. Constraints and results shows how to write the IsRadioFriendlyConstraint, and message conventions how its texts should read.