Skip to content

Commit 60a06d6

Browse files
authored
feat: include all interactions in failure message (#93)
This pull request improves the clarity and usefulness of mock verification failure messages by consistently renaming the "Interactions" context to "Matching Interactions" and, when a verification fails, adding a new "All Interactions" context to the output. This gives users better insight into both the interactions that matched the verification and all interactions that occurred on the mock. The changes also update tests to reflect the new output format. **Enhancements to failure diagnostics:** * Added a new `AppendAllInteractions` helper method to append all recorded interactions to the expectation builder when a verification fails, making it easier to debug why a verification did not pass. **Consistency and clarity improvements:** * Renamed all usages of the "Interactions" context to "Matching Interactions" across the codebase for clarity and consistency, ensuring that the output clearly distinguishes between interactions that matched the verification and all interactions. **Test updates:** * Updated test expectations to check for the new "Matching Interactions" and "All Interactions" sections in verification failure messages, ensuring tests align with the improved diagnostic output.
1 parent ebe8794 commit 60a06d6

18 files changed

Lines changed: 299 additions & 81 deletions

Source/aweXpect.Mockolate/ThatVerificationResult.Between.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,27 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
7474
{
7575
string interactionsText = Formatter.Format(interactions, FormattingOptions.MultipleLines);
7676
expectationBuilder.UpdateContexts(contexts => contexts
77-
.Remove("Interactions")
78-
.Add(new ResultContext.SyncCallback("Interactions", () => interactionsText)));
77+
.Remove("Matching Interactions")
78+
.Add(new ResultContext.SyncCallback("Matching Interactions", () => interactionsText)));
7979
_count = interactions.Length;
8080
return interactions.Length >= minimum && interactions.Length <= maximum;
8181
})
8282
? Outcome.Success
8383
: Outcome.Failure;
84+
if (Outcome == Outcome.Failure)
85+
{
86+
AppendAllInteractions(expectationBuilder,
87+
((IVerificationResult<TVerify>)actual).Object as IMock);
88+
}
8489
return this;
8590
}
8691
catch (MockVerificationTimeoutException)
8792
{
8893
string interactionsText = Formatter.Format(((IVerificationResult)actual).MockInteractions,
8994
FormattingOptions.MultipleLines);
9095
expectationBuilder.UpdateContexts(contexts => contexts
91-
.Remove("Interactions")
92-
.Add(new ResultContext.SyncCallback("Interactions",
96+
.Remove("Matching Interactions")
97+
.Add(new ResultContext.SyncCallback("Matching Interactions",
9398
() => interactionsText)));
9499
Outcome = Outcome.Failure;
95100
return this;
@@ -103,12 +108,17 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
103108
{
104109
string context = Formatter.Format(interactions, FormattingOptions.MultipleLines);
105110
expectationBuilder.UpdateContexts(contexts => contexts.Add(
106-
new ResultContext.SyncCallback("Interactions", () => context)));
111+
new ResultContext.SyncCallback("Matching Interactions", () => context)));
107112
_count = interactions.Length;
108113
return interactions.Length >= minimum && interactions.Length <= maximum;
109114
})
110115
? Outcome.Success
111116
: Outcome.Failure;
117+
if (Outcome == Outcome.Failure)
118+
{
119+
AppendAllInteractions(expectationBuilder,
120+
((IVerificationResult<TVerify>)actual).Object as IMock);
121+
}
112122
return this;
113123
}
114124

Source/aweXpect.Mockolate/ThatVerificationResult.Then.cs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ public ConstraintResult IsMetBy(VerificationResult<T> actual)
6363
string context = Formatter.Format(((IVerificationResult)actual).MockInteractions,
6464
FormattingOptions.MultipleLines);
6565
expectationBuilder.UpdateContexts(contexts => contexts.Add(
66-
new ResultContext.SyncCallback("Interactions", () => context)));
66+
new ResultContext.SyncCallback("Matching Interactions", () => context)));
67+
AppendAllInteractions(expectationBuilder,
68+
((IVerificationResult<T>)actual).Object as IMock);
6769
}
6870

6971
return this;

Source/aweXpect.Mockolate/ThatVerificationResult.Times.cs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -74,22 +74,27 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
7474
{
7575
string interactionsText = Formatter.Format(interactions, FormattingOptions.MultipleLines);
7676
expectationBuilder.UpdateContexts(contexts => contexts
77-
.Remove("Interactions")
78-
.Add(new ResultContext.SyncCallback("Interactions", () => interactionsText)));
77+
.Remove("Matching Interactions")
78+
.Add(new ResultContext.SyncCallback("Matching Interactions", () => interactionsText)));
7979
_count = interactions.Length;
8080
return predicate(_count);
8181
})
8282
? Outcome.Success
8383
: Outcome.Failure;
84+
if (Outcome == Outcome.Failure)
85+
{
86+
AppendAllInteractions(expectationBuilder,
87+
((IVerificationResult<TVerify>)actual).Object as IMock);
88+
}
8489
return this;
8590
}
8691
catch (MockVerificationTimeoutException)
8792
{
8893
string interactionsText = Formatter.Format(((IVerificationResult)actual).MockInteractions,
8994
FormattingOptions.MultipleLines);
9095
expectationBuilder.UpdateContexts(contexts => contexts
91-
.Remove("Interactions")
92-
.Add(new ResultContext.SyncCallback("Interactions",
96+
.Remove("Matching Interactions")
97+
.Add(new ResultContext.SyncCallback("Matching Interactions",
9398
() => interactionsText)));
9499
Outcome = Outcome.Failure;
95100
return this;
@@ -103,12 +108,17 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
103108
{
104109
string context = Formatter.Format(interactions, FormattingOptions.MultipleLines);
105110
expectationBuilder.UpdateContexts(contexts => contexts.Add(
106-
new ResultContext.SyncCallback("Interactions", () => context)));
111+
new ResultContext.SyncCallback("Matching Interactions", () => context)));
107112
_count = interactions.Length;
108113
return predicate(_count);
109114
})
110115
? Outcome.Success
111116
: Outcome.Failure;
117+
if (Outcome == Outcome.Failure)
118+
{
119+
AppendAllInteractions(expectationBuilder,
120+
((IVerificationResult<TVerify>)actual).Object as IMock);
121+
}
112122
return this;
113123
}
114124

Source/aweXpect.Mockolate/ThatVerificationResult.cs

Lines changed: 52 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
using aweXpect.Options;
99
using Mockolate;
1010
using Mockolate.Exceptions;
11+
using Mockolate.Interactions;
1112
using Mockolate.Verify;
1213

1314
namespace aweXpect;
@@ -26,6 +27,20 @@ private static string ToAmountString(this int number)
2627
_ => $"{number} times",
2728
};
2829

30+
private static void AppendAllInteractions(ExpectationBuilder expectationBuilder, IMock? mock)
31+
{
32+
if (mock is null)
33+
{
34+
return;
35+
}
36+
37+
MockInteractions allInteractions = mock.MockRegistry.Interactions;
38+
string interactionsText = Formatter.Format(allInteractions, FormattingOptions.MultipleLines);
39+
expectationBuilder.UpdateContexts(contexts => contexts
40+
.Remove("All Interactions")
41+
.Add(new ResultContext.SyncCallback("All Interactions", () => interactionsText)));
42+
}
43+
2944
private sealed class HasExactlyConstraint<TVerify>(
3045
ExpectationBuilder expectationBuilder,
3146
string it,
@@ -65,22 +80,28 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
6580
{
6681
string interactionsText = Formatter.Format(interactions, FormattingOptions.MultipleLines);
6782
expectationBuilder.UpdateContexts(contexts => contexts
68-
.Remove("Interactions")
69-
.Add(new ResultContext.SyncCallback("Interactions", () => interactionsText)));
83+
.Remove("Matching Interactions")
84+
.Add(new ResultContext.SyncCallback("Matching Interactions", () => interactionsText)));
7085
_count = interactions.Length;
7186
return interactions.Length == expected;
7287
})
7388
? Outcome.Success
7489
: Outcome.Failure;
90+
if (Outcome == Outcome.Failure)
91+
{
92+
AppendAllInteractions(expectationBuilder,
93+
((IVerificationResult<TVerify>)actual).Object as IMock);
94+
}
95+
7596
return this;
7697
}
7798
catch (MockVerificationTimeoutException)
7899
{
79100
string interactionsText = Formatter.Format(((IVerificationResult)actual).MockInteractions,
80101
FormattingOptions.MultipleLines);
81102
expectationBuilder.UpdateContexts(contexts => contexts
82-
.Remove("Interactions")
83-
.Add(new ResultContext.SyncCallback("Interactions",
103+
.Remove("Matching Interactions")
104+
.Add(new ResultContext.SyncCallback("Matching Interactions",
84105
() => interactionsText)));
85106
Outcome = Outcome.Failure;
86107
return this;
@@ -94,12 +115,17 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
94115
{
95116
string context = Formatter.Format(interactions, FormattingOptions.MultipleLines);
96117
expectationBuilder.UpdateContexts(contexts => contexts.Add(
97-
new ResultContext.SyncCallback("Interactions", () => context)));
118+
new ResultContext.SyncCallback("Matching Interactions", () => context)));
98119
_count = interactions.Length;
99120
return interactions.Length == expected;
100121
})
101122
? Outcome.Success
102123
: Outcome.Failure;
124+
if (Outcome == Outcome.Failure)
125+
{
126+
AppendAllInteractions(expectationBuilder, ((IVerificationResult<TVerify>)actual).Object as IMock);
127+
}
128+
103129
return this;
104130
}
105131

@@ -177,12 +203,17 @@ public ConstraintResult IsMetBy(VerificationResult<TVerify> actual)
177203
{
178204
string context = Formatter.Format(interactions, FormattingOptions.MultipleLines);
179205
expectationBuilder.UpdateContexts(contexts => contexts.Add(
180-
new ResultContext.SyncCallback("Interactions", () => context)));
206+
new ResultContext.SyncCallback("Matching Interactions", () => context)));
181207
_count = interactions.Length;
182208
return interactions.Length <= expected;
183209
})
184210
? Outcome.Success
185211
: Outcome.Failure;
212+
if (Outcome == Outcome.Failure)
213+
{
214+
AppendAllInteractions(expectationBuilder,
215+
((IVerificationResult<TVerify>)actual).Object as IMock);
216+
}
186217
return this;
187218
}
188219

@@ -260,22 +291,27 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
260291
{
261292
string interactionsText = Formatter.Format(interactions, FormattingOptions.MultipleLines);
262293
expectationBuilder.UpdateContexts(contexts => contexts
263-
.Remove("Interactions")
264-
.Add(new ResultContext.SyncCallback("Interactions", () => interactionsText)));
294+
.Remove("Matching Interactions")
295+
.Add(new ResultContext.SyncCallback("Matching Interactions", () => interactionsText)));
265296
_count = interactions.Length;
266297
return interactions.Length >= expected;
267298
})
268299
? Outcome.Success
269300
: Outcome.Failure;
301+
if (Outcome == Outcome.Failure)
302+
{
303+
AppendAllInteractions(expectationBuilder,
304+
((IVerificationResult<TVerify>)actual).Object as IMock);
305+
}
270306
return this;
271307
}
272308
catch (MockVerificationTimeoutException)
273309
{
274310
string interactionsText = Formatter.Format(((IVerificationResult)actual).MockInteractions,
275311
FormattingOptions.MultipleLines);
276312
expectationBuilder.UpdateContexts(contexts => contexts
277-
.Remove("Interactions")
278-
.Add(new ResultContext.SyncCallback("Interactions",
313+
.Remove("Matching Interactions")
314+
.Add(new ResultContext.SyncCallback("Matching Interactions",
279315
() => interactionsText)));
280316
Outcome = Outcome.Failure;
281317
return this;
@@ -289,12 +325,17 @@ public async Task<ConstraintResult> IsMetBy(VerificationResult<TVerify> actual,
289325
{
290326
string context = Formatter.Format(interactions, FormattingOptions.MultipleLines);
291327
expectationBuilder.UpdateContexts(contexts => contexts
292-
.Add(new ResultContext.SyncCallback("Interactions", () => context)));
328+
.Add(new ResultContext.SyncCallback("Matching Interactions", () => context)));
293329
_count = interactions.Length;
294330
return interactions.Length >= expected;
295331
})
296332
? Outcome.Success
297333
: Outcome.Failure;
334+
if (Outcome == Outcome.Failure)
335+
{
336+
AppendAllInteractions(expectationBuilder,
337+
((IVerificationResult<TVerify>)actual).Object as IMock);
338+
}
298339
return this;
299340
}
300341

Tests/aweXpect.Mockolate.Tests/ThatVerificationResultIs.AtLeastOnceTests.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,10 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
4444
invoked method MyMethod(1, false) at least once,
4545
but never found it
4646
47-
Interactions:
47+
Matching Interactions:
48+
[]
49+
50+
All Interactions:
4851
[]
4952
""");
5053
cts.Cancel();
@@ -147,7 +150,10 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
147150
invoked method MyMethod(1, false) at least once,
148151
but never found it
149152
150-
Interactions:
153+
Matching Interactions:
154+
[]
155+
156+
All Interactions:
151157
[]
152158
""");
153159
}
@@ -202,7 +208,7 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
202208
invoked method MyMethod(1, false) at least once,
203209
but never found it
204210
205-
Interactions:
211+
Matching Interactions:
206212
[
207213
[0] invoke method MyMethod(1, True),
208214
[1] invoke method MyMethod(2, True)
@@ -245,7 +251,7 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
245251
invoked method MyMethod(1, false) less than once,
246252
but found it once
247253
248-
Interactions:
254+
Matching Interactions:
249255
[
250256
[0] invoke method MyMethod(1, False)
251257
]
@@ -272,7 +278,7 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
272278
invoked method MyMethod(1, false) less than once,
273279
but found it twice
274280
275-
Interactions:
281+
Matching Interactions:
276282
[
277283
[0] invoke method MyMethod(1, False),
278284
[1] invoke method MyMethod(1, False)

Tests/aweXpect.Mockolate.Tests/ThatVerificationResultIs.AtLeastTests.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
5353
invoked method MyMethod(1, false) at least {times} times,
5454
but found it only {invocationTimes} times
5555
56-
Interactions:
56+
Matching Interactions:
5757
[
5858
*
5959
]
@@ -95,7 +95,10 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
9595
invoked method MyMethod(1, false) at least 3 times,
9696
but never found it
9797
98-
Interactions:
98+
Matching Interactions:
99+
[]
100+
101+
All Interactions:
99102
[]
100103
""");
101104
cts.Cancel();
@@ -204,7 +207,10 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
204207
invoked method MyMethod(1, false) at least {times} times,
205208
but never found it
206209
207-
Interactions:
210+
Matching Interactions:
211+
[]
212+
213+
All Interactions:
208214
[]
209215
""");
210216
}
@@ -229,7 +235,7 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
229235
invoked method MyMethod(It.IsAny<int>(), true) at least 4 times,
230236
but found it only 3 times
231237
232-
Interactions:
238+
Matching Interactions:
233239
[
234240
[0] invoke method MyMethod(1, True),
235241
[1] invoke method MyMethod(2, True),
@@ -264,7 +270,7 @@ Expected that the aweXpect.Mockolate.Tests.ThatVerificationResultIs.IMyService m
264270
invoked method MyMethod(1, false) less than {times} times,
265271
but found it {invocationTimes} times
266272
267-
Interactions:
273+
Matching Interactions:
268274
[
269275
*
270276
]

0 commit comments

Comments
 (0)