Skip to content

Commit 59c9c2f

Browse files
authored
fix: Fixed ignorance of exceptions in assertable nodes (Should, Then). Now exceptions, i.e. from Mock.Verify are handled as failed tests.
1 parent 0ed7367 commit 59c9c2f

3 files changed

Lines changed: 42 additions & 10 deletions

File tree

Directory.Build.props

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818
</PropertyGroup>
1919

2020
<ItemGroup>
21-
<None Include="..\..\LICENSE" Pack="true" PackagePath="/"/>
22-
<None Include="..\..\README.md" Pack="true" PackagePath="/"/>
21+
<None Include="..\..\LICENSE" Pack="true" PackagePath="/" Visible="False" />
22+
<None Include="..\..\README.md" Pack="true" PackagePath="/" Visible="False" />
2323
</ItemGroup>
2424

2525
<PropertyGroup>

src/Heleonix.Testing.NUnit/Internal/TestHost.cs

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,11 @@ namespace Heleonix.Testing.NUnit.Internal;
88
using System;
99
using System.Collections.Generic;
1010
using System.Linq;
11+
using System.Linq.Expressions;
12+
using System.Reflection;
1113
using System.Text.RegularExpressions;
14+
using global::NUnit.Framework;
15+
using global::NUnit.Framework.Interfaces;
1216
using global::NUnit.Framework.Internal;
1317

1418
/// <summary>
@@ -89,8 +93,17 @@ public void Execute(SpecNode node)
8993
TestExecutionContext.CurrentContext.OutWriter.WriteLine($"{new string(' ', node.NestingLevel * 4)}\u2713 {node.Description}");
9094
}
9195
}
92-
catch (Exception)
96+
catch (Exception ex)
9397
{
98+
if (ex is not AssertionException)
99+
{
100+
var result = TestExecutionContext.CurrentContext.CurrentResult;
101+
102+
result.RecordAssertion(AssertionStatus.Failed, ex.Message, ex.StackTrace);
103+
104+
result.RecordTestCompletion();
105+
}
106+
94107
if (node.IsAssertable)
95108
{
96109
TestExecutionContext.CurrentContext.OutWriter.WriteLine($"{new string(' ', node.NestingLevel * 4)}\u2717 {node.Description}");
@@ -110,7 +123,7 @@ private void ValidateAdding(SpecNode child)
110123
{
111124
if (!this.SpecStructureRules.ContainsKey(child.Type))
112125
{
113-
throw new InvalidOperationException($"The spec '{child.Type}' is not valid for the current test pattern");
126+
throw new InvalidOperationException($"The spec '{child.Type}' is not valid for the current test pattern.");
114127
}
115128

116129
var rule = this.SpecStructureRules[child.Type];
@@ -119,7 +132,7 @@ private void ValidateAdding(SpecNode child)
119132
&& !Regex.IsMatch(string.Join(",", this.specExecutionStack), rule.SpecExecutionStackRule))
120133
{
121134
throw new InvalidOperationException($"Invalid test structure: cannot place the '{child.Type}' " +
122-
$"into the '{string.Join("->", this.specExecutionStack.Reverse())}'");
135+
$"into the '{string.Join("->", this.specExecutionStack.Reverse())}'.");
123136
}
124137

125138
if (rule.PredecessorsRule != null)
@@ -129,7 +142,7 @@ private void ValidateAdding(SpecNode child)
129142
if (!Regex.IsMatch(string.Join(",", parent.Children.Reverse()), rule.PredecessorsRule))
130143
{
131144
throw new InvalidOperationException($"Invalid test structure: cannot place the '{child.Type}' " +
132-
$"after the '{string.Join("->", parent.Children)}'");
145+
$"after the '{string.Join("->", parent.Children)}'.");
133146
}
134147
}
135148
}

test/Heleonix.Testing.NUnit.Tests/Internal/TestHostTests.cs

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ namespace Heleonix.Testing.NUnit.Tests.Internal;
99
using System.Collections.Generic;
1010
using System.Reflection;
1111
using global::NUnit.Framework;
12+
using global::NUnit.Framework.Interfaces;
1213
using global::NUnit.Framework.Internal;
14+
using global::NUnit.Framework.Internal.Builders;
1315
using Heleonix.Testing.NUnit.Internal;
1416
using Moq;
1517
using Moq.Protected;
@@ -268,7 +270,7 @@ public static void ValidateAdding6()
268270
/// <summary>
269271
/// Tests writing of a failed test with marking into the Output.
270272
/// </summary>
271-
[Test(Description = "When an assertable node is throwing an exception Should write the test description as failed into the output")]
273+
[Test(Description = "When an assertable node is throwing an exception Should write the test description as failed into the output and write failure result")]
272274
public static void Execute1()
273275
{
274276
// Arrange
@@ -285,16 +287,33 @@ public static void Execute1()
285287

286288
var rootNode = new SpecNode(SpecNodeType.Root, null, () => { });
287289

288-
var node = new SpecNode(SpecNodeType.Should, "description", () => { throw new InvalidOperationException(); }, true);
290+
var node = new SpecNode(
291+
SpecNodeType.Should,
292+
"description",
293+
() => { throw new InvalidOperationException("Custom exception message."); },
294+
true);
289295

290296
rootNode.Add(node);
291297

298+
var prevResult = TestExecutionContext.CurrentContext.CurrentResult;
299+
300+
// Substitute the current test result to catch SpecNode execution.
301+
TestExecutionContext.CurrentContext.CurrentResult =
302+
TestExecutionContext.CurrentContext.CurrentTest.MakeTestResult();
303+
292304
// Act
293305
methodInfo.Invoke(testHostMock.Object, new[] { node });
294306

307+
var failCount = TestExecutionContext.CurrentContext.CurrentResult.FailCount;
308+
var message = TestExecutionContext.CurrentContext.CurrentResult.Message;
309+
var stackTrace = TestExecutionContext.CurrentContext.CurrentResult.StackTrace;
310+
311+
TestExecutionContext.CurrentContext.CurrentResult = prevResult;
312+
295313
// Assert
296-
// Cannot read the NUnit Output, so rely on the 100% test coverage.
297-
Assert.True(true);
314+
Assert.That(failCount, Is.EqualTo(1));
315+
Assert.That(message, Contains.Substring("Custom exception message."));
316+
Assert.That(stackTrace, Is.Not.Empty);
298317
}
299318

300319
/// <summary>

0 commit comments

Comments
 (0)