diff --git a/Src/FluentAssertions/Common/Configuration.cs b/Src/FluentAssertions/Common/Configuration.cs
index ed6b48c28e..793f770cc5 100644
--- a/Src/FluentAssertions/Common/Configuration.cs
+++ b/Src/FluentAssertions/Common/Configuration.cs
@@ -5,6 +5,11 @@ namespace FluentAssertions.Common;
public class Configuration
{
+ ///
+ /// Defines the key for the configuration of the test framework to be assumed in FluentAssertions.
+ ///
+ private const string TestFrameworkConfigurationKey = "FluentAssertions.TestFramework";
+
#region Private Definitions
private readonly object propertiesAccessLock = new();
@@ -118,7 +123,7 @@ public string TestFrameworkName
{
if (string.IsNullOrEmpty(testFrameworkName))
{
- testFrameworkName = store.GetSetting("FluentAssertions.TestFramework");
+ testFrameworkName = store.GetSetting(TestFrameworkConfigurationKey);
}
return testFrameworkName;
diff --git a/Src/FluentAssertions/Execution/TestFrameworkProvider.cs b/Src/FluentAssertions/Execution/TestFrameworkProvider.cs
index 684e46eee7..49f88ad5af 100644
--- a/Src/FluentAssertions/Execution/TestFrameworkProvider.cs
+++ b/Src/FluentAssertions/Execution/TestFrameworkProvider.cs
@@ -6,6 +6,9 @@
namespace FluentAssertions.Execution;
+///
+/// Implements a wrapper around all supported test frameworks to throw the correct assertion exception.
+///
internal static class TestFrameworkProvider
{
#region Private Definitions
@@ -28,24 +31,24 @@ public static void Throw(string message)
{
if (testFramework is null)
{
- testFramework = DetectFramework();
+ testFramework = DetectFramework(Services.Configuration);
}
testFramework.Throw(message);
}
- private static ITestFramework DetectFramework()
+ internal static ITestFramework DetectFramework(Configuration configuration)
{
- ITestFramework detectedFramework = AttemptToDetectUsingAppSetting()
+ ITestFramework detectedFramework = AttemptToDetectUsingAppSetting(configuration)
?? AttemptToDetectUsingDynamicScanning()
?? new FallbackTestFramework();
return detectedFramework;
}
- private static ITestFramework AttemptToDetectUsingAppSetting()
+ internal static ITestFramework AttemptToDetectUsingAppSetting(Configuration configuration)
{
- string frameworkName = Services.Configuration.TestFrameworkName;
+ string frameworkName = configuration.TestFrameworkName;
if (string.IsNullOrEmpty(frameworkName))
{
return null;
@@ -54,22 +57,23 @@ private static ITestFramework AttemptToDetectUsingAppSetting()
if (!Frameworks.TryGetValue(frameworkName, out ITestFramework framework))
{
string frameworks = string.Join(", ", Frameworks.Keys);
- var message = $"FluentAssertions was configured to use {frameworkName} but the requested test framework is not supported. " +
- $"Please use one of the supported frameworks: {frameworks}";
+ var message = $"FluentAssertions was configured to use the test framework '{frameworkName}' but this is not supported. " +
+ $"Please use one of the supported frameworks: {frameworks}.";
- throw new Exception(message);
+ throw new InvalidOperationException(message);
}
if (!framework.IsAvailable)
{
string frameworks = string.Join(", ", Frameworks.Keys);
- var message = framework is LateBoundTestFramework lateBoundTestFramework
- ? $"FluentAssertions was configured to use {frameworkName} but the required test framework assembly {lateBoundTestFramework.AssemblyName} could not be found. " +
- $"Please use one of the supported frameworks: {frameworks}"
- : $"FluentAssertions was configured to use {frameworkName} but the required test framework could not be found. " +
- $"Please use one of the supported frameworks: {frameworks}";
-
- throw new Exception(message);
+ var innerMessage = framework is LateBoundTestFramework lateBoundTestFramework
+ ? $"the required assembly '{lateBoundTestFramework.AssemblyName}' could not be found"
+ : "it could not be found";
+ var message =
+ $"FluentAssertions was configured to use the test framework '{frameworkName}' but {innerMessage}. " +
+ $"Please use one of the supported frameworks: {frameworks}.";
+
+ throw new InvalidOperationException(message);
}
return framework;
diff --git a/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs b/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs
new file mode 100644
index 0000000000..924b7497ba
--- /dev/null
+++ b/Tests/FluentAssertions.Specs/Execution/TestFrameworkProviderTests.cs
@@ -0,0 +1,79 @@
+using System;
+using FluentAssertions.Common;
+using FluentAssertions.Execution;
+using Xunit;
+
+namespace FluentAssertions.Specs.Execution;
+
+public class TestFrameworkProviderTests
+{
+ [Fact]
+ public void When_running_xunit_test_implicitly_it_should_be_detected()
+ {
+ var configuration = new Configuration(new TestConfigurationStore());
+ var result = TestFrameworkProvider.DetectFramework(configuration);
+
+ result.IsAvailable.Should().BeTrue();
+ result.Should().BeOfType();
+ }
+
+ [Fact]
+ public void When_running_xunit_test_explicitly_it_should_be_detected()
+ {
+ var configuration = new Configuration(new TestConfigurationStore())
+ {
+ TestFrameworkName = "xunit2"
+ };
+ var result = TestFrameworkProvider.DetectFramework(configuration);
+
+ result.IsAvailable.Should().BeTrue();
+ result.Should().BeOfType();
+ }
+
+ [Fact]
+ public void When_running_test_with_unknown_test_framework_it_should_throw()
+ {
+ var configuration = new Configuration(new TestConfigurationStore())
+ {
+ TestFrameworkName = "foo"
+ };
+
+ this.Invoking(_ => TestFrameworkProvider.AttemptToDetectUsingAppSetting(configuration))
+ .Should().Throw()
+ .WithMessage("FluentAssertions was configured to use the test framework 'foo' but this is not supported."
+ + " Please use one of the supported frameworks: mspec, nspec3, nunit, mstestv2, xunit2.");
+ }
+
+ [Fact]
+ public void When_running_test_with_direct_bound_but_unavailable_test_framework_it_should_throw()
+ {
+ var configuration = new Configuration(new TestConfigurationStore())
+ {
+ TestFrameworkName = "nspec3"
+ };
+
+ this.Invoking(_ => TestFrameworkProvider.AttemptToDetectUsingAppSetting(configuration))
+ .Should().Throw()
+ .WithMessage("FluentAssertions was configured to use the test framework 'nspec3' but it could not be found."
+ + " Please use one of the supported frameworks: mspec, nspec3, nunit, mstestv2, xunit2.");
+ }
+
+ [Fact]
+ public void When_running_test_with_late_bound_but_unavailable_test_framework_it_should_throw()
+ {
+ var configuration = new Configuration(new TestConfigurationStore())
+ {
+ TestFrameworkName = "nunit"
+ };
+
+ this.Invoking(_ => TestFrameworkProvider.AttemptToDetectUsingAppSetting(configuration))
+ .Should().Throw()
+ .WithMessage("FluentAssertions was configured to use the test framework 'nunit' but the required assembly 'nunit.framework' could not be found."
+ + " Please use one of the supported frameworks: mspec, nspec3, nunit, mstestv2, xunit2.");
+ }
+
+ private sealed class TestConfigurationStore : IConfigurationStore
+ {
+ string IConfigurationStore.GetSetting(string name) => string.Empty;
+ }
+}