diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 35ad301b6..3ebd41d34 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -20,7 +20,9 @@ jobs:
- uses: actions/checkout@v4
- name: 'Execute Tests'
- run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
+ run: |
+ dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
+ dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
linux-build-and-run:
name: Run Tests on Linux
@@ -33,7 +35,9 @@ jobs:
- uses: actions/checkout@v4
- name: 'Execute Tests'
- run: dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
+ run: |
+ dotnet test './test/WireMock.Net.Tests/WireMock.Net.Tests.csproj' -c Release --framework net8.0
+ dotnet test './test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj' -c Release --framework net8.0
- name: Install .NET Aspire workload
run: dotnet workload install aspire
diff --git a/WireMock.Net Solution.sln b/WireMock.Net Solution.sln
index c262e192a..98ae19beb 100644
--- a/WireMock.Net Solution.sln
+++ b/WireMock.Net Solution.sln
@@ -131,6 +131,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.Aspire.TestApp
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspireApp1.AppHostOriginal", "examples-Aspire\AspireApp1.AppHostOriginal\AspireApp1.AppHostOriginal.csproj", "{C9210DA3-F390-4598-8512-349A473FE9C9}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WireMock.Net.TUnit", "src\WireMock.Net.TUnit\WireMock.Net.TUnit.csproj", "{91024A93-848F-4A02-AF53-5EBE5834E23C}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "WireMock.Net.TUnitTests", "test\WireMock.Net.TUnitTests\WireMock.Net.TUnitTests.csproj", "{4CD237F7-B616-46B8-872F-E49B4BBB3EAE}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -317,6 +321,14 @@ Global
{C9210DA3-F390-4598-8512-349A473FE9C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C9210DA3-F390-4598-8512-349A473FE9C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C9210DA3-F390-4598-8512-349A473FE9C9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {91024A93-848F-4A02-AF53-5EBE5834E23C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {91024A93-848F-4A02-AF53-5EBE5834E23C}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {91024A93-848F-4A02-AF53-5EBE5834E23C}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {91024A93-848F-4A02-AF53-5EBE5834E23C}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4CD237F7-B616-46B8-872F-E49B4BBB3EAE}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -369,6 +381,8 @@ Global
{CE602F57-FEF8-4559-A9E0-6200BE1BF398} = {0BB8B634-407A-4610-A91F-11586990767A}
{F1B5999D-D22E-48A6-AB86-18A7876BD32E} = {0BB8B634-407A-4610-A91F-11586990767A}
{C9210DA3-F390-4598-8512-349A473FE9C9} = {AD474543-0715-49F2-A284-936B060BF736}
+ {91024A93-848F-4A02-AF53-5EBE5834E23C} = {8F890C6F-9ACC-438D-928A-AD61CDA862F2}
+ {4CD237F7-B616-46B8-872F-E49B4BBB3EAE} = {0BB8B634-407A-4610-A91F-11586990767A}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {DC539027-9852-430C-B19F-FD035D018458}
diff --git a/azure-pipelines-ci.yml b/azure-pipelines-ci.yml
index 834ef5b20..3b2523fc9 100644
--- a/azure-pipelines-ci.yml
+++ b/azure-pipelines-ci.yml
@@ -38,7 +38,7 @@ jobs:
# See: https://docs.sonarsource.com/sonarcloud/enriching/test-coverage/dotnet-test-coverage
- script: |
- dotnet sonarscanner begin /k:"WireMock-Net_WireMock.Net" /o:"wiremock-net" /d:sonar.branch.name=$(Build.SourceBranchName) /d:sonar.host.url="https://sonarcloud.io" /d:sonar.token="$(SONAR_TOKEN)" /d:sonar.pullrequest.provider=github /d:sonar.dotnet.excludeTestProjects=true /d:sonar.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
+ dotnet sonarscanner begin /k:"WireMock-Net_WireMock.Net" /o:"wiremock-net" /d:sonar.branch.name=$(Build.SourceBranchName) /d:sonar.host.url="https://sonarcloud.io" /d:sonar.token="$(SONAR_TOKEN)" /d:sonar.pullrequest.provider=github /d:sonar.cs.vscoveragexml.reportsPaths=**/wiremock-coverage-*.xml /d:sonar.verbose=true
displayName: 'Begin analysis on SonarCloud'
condition: and(succeeded(), ne(variables['Build.Reason'], 'PullRequest')) # Do not run for PullRequests
@@ -52,13 +52,14 @@ jobs:
- task: CmdLine@2
inputs:
script: |
- dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-1.xml"
- displayName: 'Execute WireMock.Net.Tests with Coverage'
+ dotnet-coverage collect "dotnet test ./test/WireMock.Net.Tests/WireMock.Net.Tests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-xunit.xml"
+ dotnet-coverage collect "dotnet test ./test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj --configuration Debug --no-build --framework net8.0" -f xml -o "wiremock-coverage-tunit.xml"
+ displayName: 'Execute WireMock.Net.Tests with Coverage'
- task: CmdLine@2
inputs:
script: |
- dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-2.xml"
+ dotnet-coverage collect "dotnet test ./test/WireMock.Net.Aspire.Tests/WireMock.Net.Aspire.Tests.csproj --configuration Debug --no-build" -f xml -o "wiremock-coverage-aspire.xml"
displayName: 'Execute WireMock.Net.Aspire.Tests with Coverage'
- task: CmdLine@2
diff --git a/src/WireMock.Net.TUnit/TUnitWireMockLogger.cs b/src/WireMock.Net.TUnit/TUnitWireMockLogger.cs
new file mode 100644
index 000000000..a38926004
--- /dev/null
+++ b/src/WireMock.Net.TUnit/TUnitWireMockLogger.cs
@@ -0,0 +1,80 @@
+// Copyright © WireMock.Net
+
+using System;
+using Newtonsoft.Json;
+using Stef.Validation;
+using TUnit.Core.Logging;
+using WireMock.Admin.Requests;
+using WireMock.Logging;
+
+namespace WireMock.Net.TUnit;
+
+///
+/// When using TUnit, this class enables to log the output from WireMock.Net to the .
+///
+// ReSharper disable once InconsistentNaming
+public sealed class TUnitWireMockLogger : IWireMockLogger
+{
+ private readonly TUnitLogger _tUnitLogger;
+
+ ///
+ /// Create a new instance on the .
+ ///
+ /// Represents a class which can be used to provide test output.
+ public TUnitWireMockLogger(TUnitLogger tUnitLogger)
+ {
+ _tUnitLogger = Guard.NotNull(tUnitLogger);
+ }
+
+ ///
+ public void Debug(string formatString, params object[] args)
+ {
+ _tUnitLogger.LogDebug(Format("Debug", formatString, args));
+ }
+
+ ///
+ public void Info(string formatString, params object[] args)
+ {
+ _tUnitLogger.LogInformation(Format("Info", formatString, args));
+ }
+
+ ///
+ public void Warn(string formatString, params object[] args)
+ {
+ _tUnitLogger.LogWarning(Format("Warning", formatString, args));
+ }
+
+ ///
+ public void Error(string formatString, params object[] args)
+ {
+ _tUnitLogger.LogError(Format("Error", formatString, args));
+ }
+
+ ///
+ public void Error(string formatString, Exception exception)
+ {
+ _tUnitLogger.LogError(Format("Error", formatString, exception.Message), exception);
+
+ if (exception is AggregateException ae)
+ {
+ ae.Handle(ex =>
+ {
+ _tUnitLogger.LogError(Format("Error", "Exception {0}", ex.Message), exception);
+ return true;
+ });
+ }
+ }
+
+ ///
+ public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminRequest)
+ {
+ var message = JsonConvert.SerializeObject(logEntryModel, Formatting.Indented);
+ _tUnitLogger.LogDebug(Format("DebugRequestResponse", "Admin[{0}] {1}", isAdminRequest, message));
+ }
+
+ private static string Format(string level, string formatString, params object[] args)
+ {
+ var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
+ return $"{DateTime.UtcNow} [{level}] : {message}";
+ }
+}
\ No newline at end of file
diff --git a/src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj b/src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj
new file mode 100644
index 000000000..47c9c3c44
--- /dev/null
+++ b/src/WireMock.Net.TUnit/WireMock.Net.TUnit.csproj
@@ -0,0 +1,38 @@
+
+
+
+ Some extensions for TUnit (TUnitLogger)
+ WireMock.Net.TUnit
+ Stef Heyenrath
+ net8.0
+ true
+ WireMock.Net.TUnit
+ WireMock.Net.Tunit
+ WireMock.Net.TUnit
+ tdd;wiremock;test;unittest;TUnit
+ {0DE0954F-8C00-4E8D-B94A-4361FC1CB34A}
+ true
+ $(AllowedOutputExtensionsInPackageBuildOutputFolder);.pdb
+ true
+ true
+ true
+ true
+ ../WireMock.Net/WireMock.Net.snk
+ true
+
+
+
+ true
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/WireMock.Net.xUnit/TestOutputHelperWireMockLogger.cs b/src/WireMock.Net.xUnit/TestOutputHelperWireMockLogger.cs
index 51570e8e3..df83bac37 100644
--- a/src/WireMock.Net.xUnit/TestOutputHelperWireMockLogger.cs
+++ b/src/WireMock.Net.xUnit/TestOutputHelperWireMockLogger.cs
@@ -73,8 +73,6 @@ public void DebugRequestResponse(LogEntryModel logEntryModel, bool isAdminReques
private static string Format(string level, string formatString, params object[] args)
{
- Guard.NotNull(formatString);
-
var message = args.Length > 0 ? string.Format(formatString, args) : formatString;
return $"{DateTime.UtcNow} [{level}] : {message}";
}
diff --git a/test/WireMock.Net.TUnitTests/TUnitTests.cs b/test/WireMock.Net.TUnitTests/TUnitTests.cs
new file mode 100644
index 000000000..fd5ef881b
--- /dev/null
+++ b/test/WireMock.Net.TUnitTests/TUnitTests.cs
@@ -0,0 +1,37 @@
+// Copyright © WireMock.Net
+
+using WireMock.Net.TUnit;
+using WireMock.RequestBuilders;
+using WireMock.ResponseBuilders;
+using WireMock.Server;
+using WireMock.Settings;
+
+namespace WireMock.Net.TUnitTests;
+
+// ReSharper disable once InconsistentNaming
+public class TUnitTests
+{
+ [Test]
+ public async Task Test_TUnitWireMockLogger()
+ {
+ // Assign
+ var path = $"/foo_{Guid.NewGuid()}";
+
+ using var server = WireMockServer.Start(new WireMockServerSettings
+ {
+ Logger = new TUnitWireMockLogger(TestContext.Current!.GetDefaultLogger())
+ });
+
+ server
+ .Given(Request.Create()
+ .WithPath(path)
+ .UsingGet())
+ .RespondWith(Response.Create().WithBody("TUnit"));
+
+ // Act
+ var response = await server.CreateClient().GetStringAsync($"{server.Url}{path}");
+
+ // Assert
+ await Assert.That(response).IsEqualTo("TUnit");
+ }
+}
\ No newline at end of file
diff --git a/test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj b/test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj
new file mode 100644
index 000000000..38793c054
--- /dev/null
+++ b/test/WireMock.Net.TUnitTests/WireMock.Net.TUnitTests.csproj
@@ -0,0 +1,18 @@
+
+
+
+ net8.0
+ enable
+ enable
+
+
+
+
+
+
+
+
+
+
+
+