From 9b359addd57d059e063ceb4bd033269ddd57f1d7 Mon Sep 17 00:00:00 2001 From: Piotr Zajac Date: Thu, 28 Sep 2023 07:41:43 +0200 Subject: [PATCH] Improve tests by making them immune to mutations --- .../AutoDataAdapterAttributeTests.cs | 59 ++++++++++++++++++- 1 file changed, 57 insertions(+), 2 deletions(-) diff --git a/src/Objectivity.AutoFixture.XUnit2.Core.Tests/Attributes/AutoDataAdapterAttributeTests.cs b/src/Objectivity.AutoFixture.XUnit2.Core.Tests/Attributes/AutoDataAdapterAttributeTests.cs index 1ea67e2f..00fc2fc3 100644 --- a/src/Objectivity.AutoFixture.XUnit2.Core.Tests/Attributes/AutoDataAdapterAttributeTests.cs +++ b/src/Objectivity.AutoFixture.XUnit2.Core.Tests/Attributes/AutoDataAdapterAttributeTests.cs @@ -8,6 +8,7 @@ using FluentAssertions; using global::AutoFixture; + using global::AutoFixture.Kernel; using global::AutoFixture.Xunit2; using Objectivity.AutoFixture.XUnit2.Core.Attributes; @@ -59,13 +60,14 @@ public void GivenTestDataWithInstance_WhenGetDataCalled_ThenAutoDataGenerationSk IFixture fixture = new Fixture(); var attribute = new AutoDataAdapterAttribute(fixture, SpecificTestClass.Create()); var methodInfo = typeof(AutoDataAdapterAttributeTests).GetMethod(nameof(this.TestMethodWithAbstractTestClass), BindingFlags.Instance | BindingFlags.NonPublic); + var expectedNumberOfParameters = methodInfo.GetParameters().Length; // Act var data = attribute.GetData(methodInfo).ToArray(); // Assert data.Should().HaveCount(1) - .And.Subject.First().Should().HaveCount(methodInfo.GetParameters().Length) + .And.Subject.First().Should().HaveCount(expectedNumberOfParameters) .And.NotContainNulls() .And.Subject.Skip(1).Should().AllBeEquivalentTo(data.First().Last()); } @@ -85,11 +87,47 @@ public void GivenEmptyTestData_WhenGetDataCalled_ThenAutoDataGenerationSkipped() data.Should().Throw(); } - protected string TestMethodWithAbstractTestClass(SpecificTestClass instance, [Frozen] string text, string message) + [Fact(DisplayName = "GIVEN test method with Frozen customization after others WHEN GetData called THEN ensure parameter is frozen on the end")] + public void GivenTestMethodWithFrozenCustomizationAfterOthers_WhenGetDataCalled_ThenEnsureParameterIsFrozenOnTheEnd() + { + // Arrange + IFixture fixture = new Fixture(); + var attribute = new AutoDataAdapterAttribute(fixture, null); + var methodInfo = typeof(AutoDataAdapterAttributeTests).GetMethod(nameof(this.TestMethodWithFrozenCustomizationBeforeOthers), BindingFlags.Instance | BindingFlags.NonPublic); + var expectedNumberOfParameters = methodInfo.GetParameters().Length; + + // Act + var data = attribute.GetData(methodInfo).ToArray(); + + // Assert + data.Should().HaveCount(1) + .And.Subject.First().Should().HaveCount(expectedNumberOfParameters) + .And.NotContainNulls() + .And.Subject.Skip(1).Should().AllSatisfy((x) => + { + var parameters = data.First(); + x.Should().Be(parameters.Last()) + .And.NotBe(parameters.First()) + .And.Subject.As().Should().Contain(StopStringCustomization.Value); + }); + } + + protected string TestMethodWithAbstractTestClass( + SpecificTestClass instance, + [Frozen] string text, + string message) { return $"{instance}: {text}, {message}"; } + protected string TestMethodWithFrozenCustomizationBeforeOthers( + string first, + [Frozen][StopString] string second, + string third) + { + return $"{first}: {second}, {third}"; + } + [SuppressMessage("Minor Code Smell", "S2094:Classes should not be empty", Justification = "Test class")] public abstract class AbstractTestClass { @@ -106,5 +144,22 @@ public static AbstractTestClass Create() return new SpecificTestClass(); } } + + protected sealed class StopStringAttribute : CustomizeWithAttribute + { + } + + protected class StopStringCustomization : ICustomization + { + public const string Value = "STOP"; + + public void Customize(IFixture fixture) + { + fixture.Customizations.Add( + new FilteringSpecimenBuilder( + new FixedBuilder(Value), + new ExactTypeSpecification(Value.GetType()))); + } + } } }