refactor(tests): migrate Database.Tests from FluentAssertions to Shouldly

Replace FluentAssertions with Shouldly across all 6 test files (94 tests).
Add ShouldlyExtensions for BeCloseTo and BeEquivalentTo patterns.
This commit is contained in:
Joseph Doherty
2026-01-29 14:40:18 -05:00
parent 04383d672c
commit 1e23616638
9 changed files with 223 additions and 152 deletions
@@ -1,6 +1,6 @@
using Dapper;
using FluentAssertions;
using JdeScoping.Database.Tests.Infrastructure;
using Shouldly;
namespace JdeScoping.Database.Tests.Procedures;
@@ -57,7 +57,7 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase
"SELECT COUNT(*) FROM MisData_Curr WHERE MisNumber = @MisNumber",
new { MisNumber = testMisNumber });
finalCurrCount.Should().Be(initialCurrCount, "Debug mode should not modify data");
finalCurrCount.ShouldBe(initialCurrCount, "Debug mode should not modify data");
}
finally
{
@@ -93,9 +93,11 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase
WHERE MisNumber = @MisNumber",
new { MisNumber = testMisNumber });
record.Should().NotBeNull("Record should be inserted to MisData_Curr");
((string)record.Status).Should().Be("Current");
((DateTime?)record.ObsoleteDate).Should().BeNull();
// Use Assert.NotNull instead of Shouldly for dynamic null check
// (Shouldly's .ShouldNotBeNull() fails with dynamic null due to runtime binding)
Assert.NotNull(record);
((string)record.Status).ShouldBe("Current");
((DateTime?)record.ObsoleteDate).ShouldBeNull();
}
finally
{
@@ -144,9 +146,9 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase
WHERE MisNumber = @MisNumber AND RevID = 'A'",
new { MisNumber = testMisNumber });
histRecord.Should().NotBeNull("Old version should be moved to MisData_Hist");
((string)histRecord.Status).Should().Be("BackLevel");
((DateTime?)histRecord.ObsoleteDate).Should().NotBeNull();
Assert.NotNull(histRecord);
((string)histRecord.Status).ShouldBe("BackLevel");
((DateTime?)histRecord.ObsoleteDate).ShouldNotBeNull();
// Assert - new version should be in current with Current status
var currRecord = await Connection.QuerySingleOrDefaultAsync<dynamic>(
@@ -155,9 +157,9 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase
WHERE MisNumber = @MisNumber AND RevID = 'B'",
new { MisNumber = testMisNumber });
currRecord.Should().NotBeNull("New version should be in MisData_Curr");
((string)currRecord.Status).Should().Be("Current");
((DateTime?)currRecord.ObsoleteDate).Should().BeNull();
Assert.NotNull(currRecord);
((string)currRecord.Status).ShouldBe("Current");
((DateTime?)currRecord.ObsoleteDate).ShouldBeNull();
}
finally
{
@@ -192,7 +194,7 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase
@"SELECT MisNumber FROM MisData_Curr WHERE MisNumber = @MisNumber",
new { MisNumber = testMisNumber });
record.Should().NotBeNull("Record should be inserted with IIS_ prefix removed");
Assert.NotNull(record);
}
finally
{
@@ -212,6 +214,6 @@ public class ProcessMisStagingDataProcedureTests : DatabaseTestBase
"EXEC dbo.usp_ProcessMisStagingData @SaveChanges = 1");
// Assert
await act.Should().NotThrowAsync();
await Should.NotThrowAsync(act);
}
}
@@ -1,6 +1,6 @@
using Dapper;
using FluentAssertions;
using JdeScoping.Database.Tests.Infrastructure;
using Shouldly;
namespace JdeScoping.Database.Tests.Procedures;
@@ -28,42 +28,42 @@ public class StoredProcedureExistsTests : DatabaseTestBase
public async Task usp_SubmitSearch_Exists()
{
var exists = await ProcedureExistsAsync("usp_SubmitSearch");
exists.Should().BeTrue("usp_SubmitSearch should be created by migration 040");
exists.ShouldBeTrue("usp_SubmitSearch should be created by migration 040");
}
[Fact]
public async Task usp_StartSearch_Exists()
{
var exists = await ProcedureExistsAsync("usp_StartSearch");
exists.Should().BeTrue("usp_StartSearch should be created by migration 041");
exists.ShouldBeTrue("usp_StartSearch should be created by migration 041");
}
[Fact]
public async Task usp_CompleteSearch_Exists()
{
var exists = await ProcedureExistsAsync("usp_CompleteSearch");
exists.Should().BeTrue("usp_CompleteSearch should be created by migration 042");
exists.ShouldBeTrue("usp_CompleteSearch should be created by migration 042");
}
[Fact]
public async Task usp_ResetPartialSearches_Exists()
{
var exists = await ProcedureExistsAsync("usp_ResetPartialSearches");
exists.Should().BeTrue("usp_ResetPartialSearches should be created by migration 043");
exists.ShouldBeTrue("usp_ResetPartialSearches should be created by migration 043");
}
[Fact]
public async Task usp_ValidateSearchCriteria_Exists()
{
var exists = await ProcedureExistsAsync("usp_ValidateSearchCriteria");
exists.Should().BeTrue("usp_ValidateSearchCriteria should be created by migration 048");
exists.ShouldBeTrue("usp_ValidateSearchCriteria should be created by migration 048");
}
[Fact]
public async Task usp_ProcessMisStagingData_Exists()
{
var exists = await ProcedureExistsAsync("usp_ProcessMisStagingData");
exists.Should().BeTrue("usp_ProcessMisStagingData should be created by migration 049");
exists.ShouldBeTrue("usp_ProcessMisStagingData should be created by migration 049");
}
[Fact]
@@ -86,7 +86,7 @@ public class StoredProcedureExistsTests : DatabaseTestBase
WHERE schema_id = SCHEMA_ID('dbo')
AND name LIKE 'usp_%'");
actualCount.Should().BeGreaterThanOrEqualTo(
actualCount.ShouldBeGreaterThanOrEqualTo(
expectedProcedures.Length,
$"Database should have at least {expectedProcedures.Length} stored procedures");
}
@@ -1,8 +1,8 @@
using Dapper;
using FluentAssertions;
using JdeScoping.Core.Models.Search;
using JdeScoping.Database.Tests.Infrastructure;
using Microsoft.Data.SqlClient;
using Shouldly;
namespace JdeScoping.Database.Tests.Procedures;
@@ -26,7 +26,7 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase
new { SearchId = searchId });
// Assert
await act.Should().NotThrowAsync();
await Should.NotThrowAsync(act);
}
[Fact]
@@ -38,9 +38,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase
new { SearchId = 99999 });
// Assert
var ex = await act.Should().ThrowAsync<SqlException>();
ex.Which.Number.Should().Be(50001);
ex.Which.Message.Should().Contain("Search ID 99999 not found");
var ex = await Should.ThrowAsync<SqlException>(act);
ex.Number.ShouldBe(50001);
ex.Message.ShouldContain("Search ID 99999 not found");
}
[Fact]
@@ -55,9 +55,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase
new { SearchId = searchId });
// Assert
var ex = await act.Should().ThrowAsync<SqlException>();
ex.Which.Number.Should().Be(50002);
ex.Which.Message.Should().Contain("has no criteria");
var ex = await Should.ThrowAsync<SqlException>(act);
ex.Number.ShouldBe(50002);
ex.Message.ShouldContain("has no criteria");
}
[Fact]
@@ -72,9 +72,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase
new { SearchId = searchId });
// Assert
var ex = await act.Should().ThrowAsync<SqlException>();
ex.Which.Number.Should().Be(50002);
ex.Which.Message.Should().Contain("has no criteria");
var ex = await Should.ThrowAsync<SqlException>(act);
ex.Number.ShouldBe(50002);
ex.Message.ShouldContain("has no criteria");
}
[Fact]
@@ -89,9 +89,9 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase
new { SearchId = searchId });
// Assert
var ex = await act.Should().ThrowAsync<SqlException>();
ex.Which.Number.Should().Be(50003);
ex.Which.Message.Should().Contain("has invalid JSON");
var ex = await Should.ThrowAsync<SqlException>(act);
ex.Number.ShouldBe(50003);
ex.Message.ShouldContain("has invalid JSON");
}
[Fact]
@@ -106,6 +106,6 @@ public class ValidateSearchCriteriaProcedureTests : DatabaseTestBase
new { SearchId = searchId });
// Assert
await act.Should().NotThrowAsync();
await Should.NotThrowAsync(act);
}
}