Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor tests #326

Merged
merged 3 commits into from
Nov 23, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions test/Guidelines.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# Base Registries Unit Testing Guidelines

## Introduction
This document outlines the guidelines for writing unit tests in C# following the "Given-When-Then" principle and encourages the use of the builder pattern for test data creation.

## Given-When-Then Principle
We adhere to the "Given-When-Then" principle to structure our unit tests. The test method naming follows the format:
- **Given**: Describes the initial conditions.
- **When**: Describes the action or scenario.
- **Then**: Describes the expected outcome.

### Folder Structure
- Tests related to "When" should be organized within folders that represent the action or scenario, e.g., "WhenProposingStreetName."

### Class Structure
- Each test class should correspond to the "Given" part, e.g., "GivenMunicipality."

### Method Naming
- Test method names should follow the format: "With{Condition}_Then{Outcome}," where:
- "With" represents the condition being set up.
- "Then" represents the expected outcome of the test.

## Builder Pattern for Test Data
We encourage the use of the builder pattern to create test data. This approach provides a cleaner and more flexible way to set up test scenarios.

### Test Data Builders
- Create separate test data builder classes or methods for each class under test.
- Builders should have clear and expressive methods for configuring the object's state.
- Default values being set by the builder should be documented in a summary
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,16 @@ namespace StreetNameRegistry.Tests.AggregateTests.WhenAddingMunicipalityFacility
using Municipality;
using Municipality.Commands;
using Municipality.Events;
using Extensions;
using Testing;
using Xunit;
using Xunit.Abstractions;

public sealed class GivenMunicipalityHasAFacilityLanguage : StreetNameRegistryTest
public sealed class GivenMunicipality : StreetNameRegistryTest
{
private readonly MunicipalityId _municipalityId;
private readonly MunicipalityStreamId _streamId;

public GivenMunicipalityHasAFacilityLanguage(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
public GivenMunicipality(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
Fixture.Customize(new InfrastructureCustomization());
Fixture.Customize(new WithFixedMunicipalityId());
Expand All @@ -30,63 +29,52 @@ public GivenMunicipalityHasAFacilityLanguage(ITestOutputHelper testOutputHelper)
[InlineData(Language.French)]
[InlineData(Language.English)]
[InlineData(Language.German)]
public void ThenNone(Language language)
public void ThenMunicipalityFacilityLanguageWasAdded(Language language)
{
Fixture.Register(() => language);
var commandLanguageAdded = Fixture.Create<AddFacilityLanguageToMunicipality>();

Assert(new Scenario()
.Given(_streamId, new object[]
{
Fixture.Create<MunicipalityWasImported>(),
Fixture.Create<MunicipalityFacilityLanguageWasAdded>()
})
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>())
.When(commandLanguageAdded)
.ThenNone());
.Then(new Fact(_streamId, new MunicipalityFacilityLanguageWasAdded(_municipalityId, language))));
}

[Theory]
[InlineData(Language.Dutch)]
[InlineData(Language.French)]
[InlineData(Language.English)]
[InlineData(Language.German)]
public void AndWasRemoved_FacilityLanguageWasAdded(Language language)
public void WithAlreadyExistingFacilityLanguage_ThenNone(Language language)
{
Fixture.Register(() => language);
var commandLanguageAdded = Fixture.Create<AddFacilityLanguageToMunicipality>();

Assert(new Scenario()
.Given(_streamId, new object[]
{
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>(),
Fixture.Create<MunicipalityFacilityLanguageWasAdded>(),
Fixture.Create<MunicipalityFacilityLanguageWasRemoved>()
})
Fixture.Create<MunicipalityFacilityLanguageWasAdded>())
.When(commandLanguageAdded)
.Then(new[]
{
new Fact(_streamId, new MunicipalityFacilityLanguageWasAdded(_municipalityId, language))
}));
.ThenNone());
}

[Fact]
public void AndHasMultipleLanguages_TheCorrectOneWasAdded()
[Theory]
[InlineData(Language.Dutch)]
[InlineData(Language.French)]
[InlineData(Language.English)]
[InlineData(Language.German)]
public void WithRemovedFacilityLanguage_ThenFacilityLanguageWasAdded(Language language)
{
var languageAddGerman = Fixture.Create<AddFacilityLanguageToMunicipality>().WithLanguage(Language.German);
var commandAddedEnglish = Fixture.Create<AddFacilityLanguageToMunicipality>().WithLanguage(Language.English);
var commandAddedDutch = Fixture.Create<AddFacilityLanguageToMunicipality>().WithLanguage(Language.Dutch);
Fixture.Register(() => language);
var commandLanguageAdded = Fixture.Create<AddFacilityLanguageToMunicipality>();

Assert(new Scenario()
.Given(_streamId, new object[]
{
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>(),
commandAddedEnglish.ToEvent(),
commandAddedDutch.ToEvent()
})
.When(languageAddGerman)
.Then(new[]
{
new Fact(_streamId, new MunicipalityFacilityLanguageWasAdded(_municipalityId, Language.German))
}));
Fixture.Create<MunicipalityFacilityLanguageWasAdded>(),
Fixture.Create<MunicipalityFacilityLanguageWasRemoved>())
.When(commandLanguageAdded)
.Then(new Fact(_streamId, new MunicipalityFacilityLanguageWasAdded(_municipalityId, language))));
}
}
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,12 @@ namespace StreetNameRegistry.Tests.AggregateTests.WhenAddingMunicipalityOfficial
using Xunit;
using Xunit.Abstractions;

public sealed class GivenMunicipalityHasAOfficialLanguage : StreetNameRegistryTest
public sealed class GivenMunicipality : StreetNameRegistryTest
{
private readonly MunicipalityId _municipalityId;
private readonly MunicipalityStreamId _streamId;

public GivenMunicipalityHasAOfficialLanguage(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
public GivenMunicipality(ITestOutputHelper testOutputHelper) : base(testOutputHelper)
{
Fixture.Customize(new InfrastructureCustomization());
Fixture.Customize(new WithFixedMunicipalityId());
Expand All @@ -30,17 +30,31 @@ public GivenMunicipalityHasAOfficialLanguage(ITestOutputHelper testOutputHelper)
[InlineData(Language.French)]
[InlineData(Language.English)]
[InlineData(Language.German)]
public void ThenNone(Language language)
public void ThenMunicipalityOfficialLanguageWasAdded(Language language)
{
Fixture.Register(() => language);
var commandLanguageAdded = Fixture.Create<AddOfficialLanguageToMunicipality>();
Assert(new Scenario()
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>())
.When(commandLanguageAdded)
.Then(new Fact(_streamId, new MunicipalityOfficialLanguageWasAdded(_municipalityId, language))));
}

[Theory]
[InlineData(Language.Dutch)]
[InlineData(Language.French)]
[InlineData(Language.English)]
[InlineData(Language.German)]
public void WithAlreadyExistingOfficialLanguage_ThenNone(Language language)
{
Fixture.Register(() => language);
var commandLanguageAdded = Fixture.Create<AddOfficialLanguageToMunicipality>();

Assert(new Scenario()
.Given(_streamId, new object[]
{
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>(),
Fixture.Create<MunicipalityOfficialLanguageWasAdded>()
})
Fixture.Create<MunicipalityOfficialLanguageWasAdded>())
.When(commandLanguageAdded)
.ThenNone());
}
Expand All @@ -50,43 +64,33 @@ public void ThenNone(Language language)
[InlineData(Language.French)]
[InlineData(Language.English)]
[InlineData(Language.German)]
public void AndWasRemoved_OfficialLanguageWasAdded(Language language)
public void WithRemovedOfficialLanguage_ThenOfficialLanguageWasAdded(Language language)
{
Fixture.Register(() => language);
var commandLanguageAdded = Fixture.Create<AddOfficialLanguageToMunicipality>();

Assert(new Scenario()
.Given(_streamId, new object[]
{
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>(),
Fixture.Create<MunicipalityOfficialLanguageWasAdded>(),
Fixture.Create<MunicipalityOfficialLanguageWasRemoved>()
})
Fixture.Create<MunicipalityOfficialLanguageWasRemoved>())
.When(commandLanguageAdded)
.Then(new[]
{
new Fact(_streamId, new MunicipalityOfficialLanguageWasAdded(_municipalityId, language))
}));
.Then(new Fact(_streamId, new MunicipalityOfficialLanguageWasAdded(_municipalityId, language))));
}

[Fact]
public void AndHasMultipleLanguages_TheCorrectOneWasAdded()
public void WithOtherExistingLanguages_ThenAddTheNonExistingLanguage()
{
var languageAddGerman = Fixture.Create<AddOfficialLanguageToMunicipality>().WithLanguage(Language.German);
var commandAddedEnglish = Fixture.Create<AddOfficialLanguageToMunicipality>().WithLanguage(Language.English);
var commandAddedDutch = Fixture.Create<AddOfficialLanguageToMunicipality>().WithLanguage(Language.Dutch);
Assert(new Scenario()
.Given(_streamId, new object[]
{
.Given(_streamId,
Fixture.Create<MunicipalityWasImported>(),
commandAddedEnglish.ToEvent(),
commandAddedDutch.ToEvent()
})
commandAddedDutch.ToEvent())
.When(languageAddGerman)
.Then(new[]
{
new Fact(_streamId, new MunicipalityOfficialLanguageWasAdded(_municipalityId, Language.German))
}));
.Then(new Fact(_streamId, new MunicipalityOfficialLanguageWasAdded(_municipalityId, Language.German))));
}
}
}

This file was deleted.

Loading
Loading