Skip to content

Commit

Permalink
Merge pull request #8 from JohnnySenior/users/JohnnySenior/foundation…
Browse files Browse the repository at this point in the history
…s-throw-meaningful-exception

FOUNDATIONS: Throw Meaningful Exception
  • Loading branch information
cjdutoit authored Apr 28, 2024
2 parents 40b2b13 + 5f2cc34 commit feb49d8
Show file tree
Hide file tree
Showing 20 changed files with 667 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

<ItemGroup>
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="STX.EFxceptions.Abstractions" Version="0.1.6" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,4 +44,8 @@
</None>
</ItemGroup>

<ItemGroup>
<PackageReference Include="STX.EFxceptions.Abstractions" Version="0.1.6" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
Expand All @@ -9,7 +9,9 @@
</PropertyGroup>

<ItemGroup>
<PackageReference Include="FluentAssertions" Version="6.12.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.6.0" />
<PackageReference Include="STX.EFxceptions.Abstractions" Version="0.1.6" />
<PackageReference Include="xunit" Version="2.4.2" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.5">
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
Expand All @@ -24,5 +26,10 @@
<ItemGroup>
<ProjectReference Include="..\STX.EFxceptions.SqlServer.Base\STX.EFxceptions.SqlServer.Base.csproj" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="CleanMoq" Version="42.42.42" />
<PackageReference Include="Tynamix.ObjectFiller" Version="1.5.8" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,343 @@
// ----------------------------------------------------------------------------------
// Copyright(c) The Standard Organization: A coalition of the Good-Hearted Engineers
// ----------------------------------------------------------------------------------

using FluentAssertions;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore;
using Moq;
using STX.EFxceptions.Abstractions.Models.Exceptions;
using STX.EFxceptions.SqlServer.Base.Models.Exceptions;
using Xunit;

namespace STX.EFxceptions.SqlServer.Base.Tests.Unit.Services.Foundations
{
public partial class SqlServerEFxceptionServiceTests
{
[Fact]
public void ShouldThrowDbUpdateExceptionIfErrorCodeIsNotRecognized()
{
// given
int sqlForeignKeyConstraintConflictErrorCode = 0000;
string randomErrorMessage = CreateRandomErrorMessage();

SqlException foreignKeyConstraintConflictException =
CreateSqlException(
message: randomErrorMessage,
errorCode: sqlForeignKeyConstraintConflictErrorCode);

string randomDbUpdateExceptionMessage = CreateRandomErrorMessage();

var dbUpdateException = new DbUpdateException(
message: randomDbUpdateExceptionMessage,
innerException: foreignKeyConstraintConflictException);

DbUpdateException expectedDbUpdateException = dbUpdateException;

this.sqlServerErrorBrokerMock.Setup(broker =>
broker.GetErrorCode(foreignKeyConstraintConflictException))
.Returns(sqlForeignKeyConstraintConflictErrorCode);

// when
DbUpdateException actualDbUpdateException =
Assert.Throws<DbUpdateException>(() =>
this.sqlServerEFxceptionService
.ThrowMeaningfulException(dbUpdateException));

// then
actualDbUpdateException.Should()
.BeEquivalentTo(
expectation: expectedDbUpdateException,
config: options => options
.Excluding(ex => ex.TargetSite)
.Excluding(ex => ex.StackTrace)
.Excluding(ex => ex.Source)
.Excluding(ex => ex.InnerException.TargetSite)
.Excluding(ex => ex.InnerException.StackTrace)
.Excluding(ex => ex.InnerException.Source));
this.sqlServerErrorBrokerMock.Verify(broker => broker
.GetErrorCode(foreignKeyConstraintConflictException),
Times.Once());

this.sqlServerErrorBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowInvalidColumnNameSqlException()
{
// given
int sqlInvalidColumnNameErrorCode = 207;
string randomErrorMessage = CreateRandomErrorMessage();

SqlException invalidColumnNameExceptionThrown =
CreateSqlException(
message: randomErrorMessage,
errorCode: sqlInvalidColumnNameErrorCode);

string randomDbUpdateExceptionMessage = CreateRandomErrorMessage();

var dbUpdateException = new DbUpdateException(
message: randomDbUpdateExceptionMessage,
innerException: invalidColumnNameExceptionThrown);

var invalidColumnNameSqlException =
new InvalidColumnNameSqlException(
message: invalidColumnNameExceptionThrown.Message);

var expectedInvalidColumnNameException =
new InvalidColumnNameException(
message: invalidColumnNameSqlException.Message,
innerException: invalidColumnNameSqlException);

this.sqlServerErrorBrokerMock.Setup(broker =>
broker.GetErrorCode(invalidColumnNameExceptionThrown))
.Returns(sqlInvalidColumnNameErrorCode);

// when
InvalidColumnNameException actualInvalidColumnNameException =
Assert.Throws<InvalidColumnNameException>(() =>
this.sqlServerEFxceptionService
.ThrowMeaningfulException(dbUpdateException));

// then
actualInvalidColumnNameException.Should()
.BeEquivalentTo(
expectation: expectedInvalidColumnNameException,
config: options => options
.Excluding(ex => ex.TargetSite)
.Excluding(ex => ex.StackTrace)
.Excluding(ex => ex.Source)
.Excluding(ex => ex.InnerException.TargetSite)
.Excluding(ex => ex.InnerException.StackTrace)
.Excluding(ex => ex.InnerException.Source));

this.sqlServerErrorBrokerMock.Verify(broker => broker
.GetErrorCode(invalidColumnNameExceptionThrown),
Times.Once());

this.sqlServerErrorBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowInvalidObjectNameSqlException()
{
// given
int sqlInvalidObjectNameErrorCode = 208;
string randomErrorMessage = CreateRandomErrorMessage();

SqlException invalidObjectNameExceptionThrown =
CreateSqlException(
message: randomErrorMessage,
errorCode: sqlInvalidObjectNameErrorCode);

string randomDbUpdateExceptionMessage = CreateRandomErrorMessage();

var dbUpdateException = new DbUpdateException(
message: randomDbUpdateExceptionMessage,
innerException: invalidObjectNameExceptionThrown);

var invalidObjectNameSqlException =
new InvalidObjectNameSqlException(
message: invalidObjectNameExceptionThrown.Message);

var expectedInvalidObjectNameException =
new InvalidObjectNameException(
message: invalidObjectNameSqlException.Message,
innerException: invalidObjectNameSqlException);

this.sqlServerErrorBrokerMock.Setup(broker =>
broker.GetErrorCode(invalidObjectNameExceptionThrown))
.Returns(sqlInvalidObjectNameErrorCode);

// when
InvalidObjectNameException actualInvalidObjectNameException =
Assert.Throws<InvalidObjectNameException>(() =>
this.sqlServerEFxceptionService
.ThrowMeaningfulException(dbUpdateException));

// then
actualInvalidObjectNameException.Should()
.BeEquivalentTo(
expectation: expectedInvalidObjectNameException,
config: options => options
.Excluding(ex => ex.TargetSite)
.Excluding(ex => ex.StackTrace)
.Excluding(ex => ex.Source)
.Excluding(ex => ex.InnerException.TargetSite)
.Excluding(ex => ex.InnerException.StackTrace)
.Excluding(ex => ex.InnerException.Source));
this.sqlServerErrorBrokerMock.Verify(broker => broker
.GetErrorCode(invalidObjectNameExceptionThrown),
Times.Once());

this.sqlServerErrorBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowForeignKeyConstraintConflictSqlException()
{
// given
int sqlForeignKeyConstraintConflictErrorCode = 547;
string randomErrorMessage = CreateRandomErrorMessage();

SqlException foreignKeyConstraintConflictExceptionThrown =
CreateSqlException(
message: randomErrorMessage,
errorCode: sqlForeignKeyConstraintConflictErrorCode);

string randomDbUpdateExceptionMessage = CreateRandomErrorMessage();

var dbUpdateException = new DbUpdateException(
message: randomDbUpdateExceptionMessage,
innerException: foreignKeyConstraintConflictExceptionThrown);

var foreignKeyConstraintConflictSqlException =
new ForeignKeyConstraintConflictSqlException(
message: foreignKeyConstraintConflictExceptionThrown.Message);

var expectedForeignKeyConstraintConflictException =
new ForeignKeyConstraintConflictException(
message: foreignKeyConstraintConflictSqlException.Message,
innerException: foreignKeyConstraintConflictSqlException);

this.sqlServerErrorBrokerMock.Setup(broker =>
broker.GetErrorCode(foreignKeyConstraintConflictExceptionThrown))
.Returns(sqlForeignKeyConstraintConflictErrorCode);

// when
ForeignKeyConstraintConflictException actualForeignKeyConstraintConflictException =
Assert.Throws<ForeignKeyConstraintConflictException>(() =>
this.sqlServerEFxceptionService
.ThrowMeaningfulException(dbUpdateException));

// then
actualForeignKeyConstraintConflictException.Should()
.BeEquivalentTo(
expectation: expectedForeignKeyConstraintConflictException,
config: options => options
.Excluding(ex => ex.TargetSite)
.Excluding(ex => ex.StackTrace)
.Excluding(ex => ex.Source)
.Excluding(ex => ex.InnerException.TargetSite)
.Excluding(ex => ex.InnerException.StackTrace)
.Excluding(ex => ex.InnerException.Source));

this.sqlServerErrorBrokerMock.Verify(broker => broker
.GetErrorCode(foreignKeyConstraintConflictExceptionThrown),
Times.Once());

this.sqlServerErrorBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowDuplicateKeyWithUniqueIndexSqlException()
{
// given
int sqlDuplicateKeyWithUniqueIndexErrorCode = 2601;
string randomErrorMessage = CreateRandomErrorMessage();

SqlException duplicateKeyWithUniqueIndexExceptionThrown =
CreateSqlException(
message: randomErrorMessage,
errorCode: sqlDuplicateKeyWithUniqueIndexErrorCode);

string randomDbUpdateExceptionMessage = CreateRandomErrorMessage();

var dbUpdateException = new DbUpdateException(
message: randomDbUpdateExceptionMessage,
innerException: duplicateKeyWithUniqueIndexExceptionThrown);

var duplicateKeyWithUniqueIndexSqlException =
new DuplicateKeyWithUniqueIndexSqlException(
message: duplicateKeyWithUniqueIndexExceptionThrown.Message);

var expectedDuplicateKeyWithUniqueIndexException =
new DuplicateKeyWithUniqueIndexException(
message: duplicateKeyWithUniqueIndexSqlException.Message,
innerException: duplicateKeyWithUniqueIndexSqlException);

this.sqlServerErrorBrokerMock.Setup(broker =>
broker.GetErrorCode(duplicateKeyWithUniqueIndexExceptionThrown))
.Returns(sqlDuplicateKeyWithUniqueIndexErrorCode);

// when
DuplicateKeyWithUniqueIndexException actualDuplicateKeyWithUniqueIndexException =
Assert.Throws<DuplicateKeyWithUniqueIndexException>(() =>
this.sqlServerEFxceptionService
.ThrowMeaningfulException(dbUpdateException));

// then
actualDuplicateKeyWithUniqueIndexException.Should()
.BeEquivalentTo(
expectation: expectedDuplicateKeyWithUniqueIndexException,
config: options => options
.Excluding(ex => ex.TargetSite)
.Excluding(ex => ex.StackTrace)
.Excluding(ex => ex.Source)
.Excluding(ex => ex.InnerException.TargetSite)
.Excluding(ex => ex.InnerException.StackTrace)
.Excluding(ex => ex.InnerException.Source));

this.sqlServerErrorBrokerMock.Verify(broker => broker
.GetErrorCode(duplicateKeyWithUniqueIndexExceptionThrown),
Times.Once());

this.sqlServerErrorBrokerMock.VerifyNoOtherCalls();
}

[Fact]
public void ShouldThrowDuplicateKeySqlException()
{
// given
int sqlDuplicateKeyErrorCode = 2627;
string randomErrorMessage = CreateRandomErrorMessage();

SqlException duplicateKeyExceptionThrown =
CreateSqlException(
message: randomErrorMessage,
errorCode: sqlDuplicateKeyErrorCode);

string randomDbUpdateExceptionMessage = CreateRandomErrorMessage();

var dbUpdateException = new DbUpdateException(
message: randomDbUpdateExceptionMessage,
innerException: duplicateKeyExceptionThrown);

var duplicateKeySqlException =
new DuplicateKeySqlException(
message: duplicateKeyExceptionThrown.Message);

var expectedDuplicateKeyException =
new DuplicateKeyException(
message: duplicateKeySqlException.Message,
innerException: duplicateKeySqlException);

this.sqlServerErrorBrokerMock.Setup(broker =>
broker.GetErrorCode(duplicateKeyExceptionThrown))
.Returns(sqlDuplicateKeyErrorCode);

// when
DuplicateKeyException actualDuplicateKeyException =
Assert.Throws<DuplicateKeyException>(() =>
this.sqlServerEFxceptionService
.ThrowMeaningfulException(dbUpdateException));
// then
actualDuplicateKeyException.Should()
.BeEquivalentTo(
expectedDuplicateKeyException,
config: options => options
.Excluding(ex => ex.TargetSite)
.Excluding(ex => ex.StackTrace)
.Excluding(ex => ex.Source)
.Excluding(ex => ex.InnerException.TargetSite)
.Excluding(ex => ex.InnerException.StackTrace)
.Excluding(ex => ex.InnerException.Source));

this.sqlServerErrorBrokerMock.Verify(broker => broker
.GetErrorCode(duplicateKeyExceptionThrown),
Times.Once());

this.sqlServerErrorBrokerMock.VerifyNoOtherCalls();
}
}
}
Loading

0 comments on commit feb49d8

Please sign in to comment.