Getting Started
Add the package, then use BunsenBurner in each test file that needs it,
dotnet add package BunsenBurner
// for AAA style tests
using static BunsenBurner.ArrangeActAssert;
or the Given/When/Then spelling,
// for BDD style tests
using static BunsenBurner.GivenWhenThen;
Take an existing test,
[Fact(DisplayName = "SerializeAsync can work with anonymous objects")]
public async Task ExampleTest()
{
// Arrange
var widget = new { Name = "Widget1", Cost = 12.50 };
var ms = new MemoryStream();
// Act
await JsonSerializer.SerializeAsync(
ms,
widget,
cancellationToken: TestContext.Current.CancellationToken
);
// Assert
Assert.Equal(
expected: "{\"Name\":\"Widget1\",\"Cost\":12.5}",
actual: Encoding.UTF8.GetString(ms.ToArray())
);
}
This can be converted to use the test builder (DSL) like so,
[Fact(DisplayName = "SerializeAsync can work with anonymous objects")]
public Task ExampleTestUsingAaaBuilder() =>
Arrange(() =>
{
var widget = new { Name = "Widget1", Cost = 12.50 };
var ms = new MemoryStream();
return (widget, ms);
})
.Act(async data =>
{
await JsonSerializer.SerializeAsync(data.ms, data.widget);
return Encoding.UTF8.GetString(data.ms.ToArray());
})
.Assert(result =>
Assert.Equal(expected: "{\"Name\":\"Widget1\",\"Cost\":12.5}", actual: result)
);
Note
Tests must always return a Task to be compatible with the DSL.
This formalizes the structure and then opens up refactoring possibilities such as pulling out a shared act method,
[Fact(DisplayName = "SerializeAsync can work with anonymous objects")]
public Task ExampleTestUsingAaaBuilder2() =>
Arrange(() =>
{
var widget = new { Name = "Widget1", Cost = 12.50 };
var ms = new MemoryStream();
return (widget, ms);
})
// pull out the shared test code
.Act(CallSerializeAsync)
.Assert(result =>
Assert.Equal(expected: "{\"Name\":\"Widget1\",\"Cost\":12.5}", actual: result)
);
// this is now a shared stage and can be used in many tests
private static async Task<string> CallSerializeAsync<T>((T, MemoryStream) data)
{
var (widget, ms) = data;
await JsonSerializer.SerializeAsync(ms, widget);
return Encoding.UTF8.GetString(ms.ToArray());
}
The idea is to use the DSL to make the shape of the test explicit, then use that shape to find code that can be shared.