Skip to content

Commit

Permalink
#2927: Misleading error message when class used in IClassFixture<> th…
Browse files Browse the repository at this point in the history
…rows exception in constructor
  • Loading branch information
bradwilson committed May 11, 2024
1 parent 1911ea7 commit f466d81
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ protected virtual object[] CreateTestClassConstructorArguments()
unusedArguments.Add(Tuple.Create(idx, parameter));
}

if (unusedArguments.Count > 0)
if (unusedArguments.Count > 0 && !Aggregator.HasExceptions)
Aggregator.Add(new TestClassException(FormatConstructorArgsMissingMessage(ctor, unusedArguments)));

return constructorArguments;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,14 @@ protected virtual void CreateClassFixture(Type fixtureType)
);
else
{
Aggregator.Run(() => ClassFixtureMappings[fixtureType] = ctor.Invoke(ctorArgs));
try
{
ClassFixtureMappings[fixtureType] = ctor.Invoke(ctorArgs);
}
catch (Exception ex)
{
Aggregator.Add(new TestClassException(string.Format(CultureInfo.CurrentCulture, "Class fixture type '{0}' threw in its constructor", fixtureType.FullName), ex.Unwrap()));
}
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/xunit.execution/Sdk/TestClassException.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ public TestClassException(string message)
: base(message)
{ }

/// <summary>
/// Initializes a new instance of the <see cref="TestClassException"/> class.
/// </summary>
/// <param name="message">The exception message.</param>
/// <param name="innerException">The inner exception.</param>
public TestClassException(string message, Exception innerException)
: base(message, innerException)
{ }

#if NETFRAMEWORK
/// <inheritdoc/>
protected TestClassException(System.Runtime.Serialization.SerializationInfo info, System.Runtime.Serialization.StreamingContext context)
Expand Down
33 changes: 30 additions & 3 deletions test/test.xunit.execution/Acceptance/FixtureAcceptanceTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -106,12 +106,17 @@ class ClassWithMissingCtorArg : IClassFixture<EmptyFixtureData>, IClassFixture<o
}

[Fact]
public void TestClassWithThrowingFixtureConstructorResultsInFailedTest()
public void TestClassWithoutCtorWithThrowingFixtureConstructorResultsInFailedTest()
{
var messages = Run<ITestFailed>(typeof(ClassWithThrowingFixtureCtor));

var msg = Assert.Single(messages);
Assert.Equal(typeof(DivideByZeroException).FullName, msg.ExceptionTypes.Single());
Assert.Collection(
msg.ExceptionTypes,
exceptionTypeName => Assert.Equal(typeof(TestClassException).FullName, exceptionTypeName),
exceptionTypeName => Assert.Equal(typeof(DivideByZeroException).FullName, exceptionTypeName)
);
Assert.Equal("Class fixture type 'FixtureAcceptanceTests+ThrowingCtorFixture' threw in its constructor", msg.Messages.First());
}

class ClassWithThrowingFixtureCtor : IClassFixture<ThrowingCtorFixture>
Expand All @@ -120,6 +125,28 @@ class ClassWithThrowingFixtureCtor : IClassFixture<ThrowingCtorFixture>
public void TheTest() { }
}

[Fact]
public void TestClassWithCtorWithThrowingFixtureConstructorResultsInFailedTest()
{
var messages = Run<ITestFailed>(typeof(ClassWithCtorAndThrowingFixtureCtor));

var msg = Assert.Single(messages);
Assert.Collection(
msg.ExceptionTypes,
exceptionTypeName => Assert.Equal(typeof(TestClassException).FullName, exceptionTypeName),
exceptionTypeName => Assert.Equal(typeof(DivideByZeroException).FullName, exceptionTypeName)
);
Assert.Equal("Class fixture type 'FixtureAcceptanceTests+ThrowingCtorFixture' threw in its constructor", msg.Messages.First());
}

class ClassWithCtorAndThrowingFixtureCtor : IClassFixture<ThrowingCtorFixture>
{
public ClassWithCtorAndThrowingFixtureCtor(ThrowingCtorFixture _) { }

[Fact]
public void TheTest() { }
}

[Fact]
public void TestClassWithThrowingFixtureDisposeResultsInFailedTest()
{
Expand Down Expand Up @@ -186,7 +213,7 @@ public void TestClassWithOptionalParameter()

class ClassWithOptionalCtorArg : IClassFixture<EmptyFixtureData>
{
public ClassWithOptionalCtorArg(EmptyFixtureData fixture, [Optional]int x, [Optional]object y)
public ClassWithOptionalCtorArg(EmptyFixtureData fixture, [Optional] int x, [Optional] object y)
{
Assert.NotNull(fixture);
Assert.Equal(0, x);
Expand Down

0 comments on commit f466d81

Please sign in to comment.