Skip to content

Commit 647395f

Browse files
authored
Merge pull request #42 from atc-net/feature/wait-for-call
Make WaitForCall extension accept matching calls made before waiting
2 parents a5adede + 7ef2d38 commit 647395f

File tree

2 files changed

+138
-71
lines changed

2 files changed

+138
-71
lines changed

src/Atc.Test/SubstituteExtensions.cs

Lines changed: 137 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// ReSharper disable AsyncVoidLambda
2+
using NSubstitute.Exceptions;
3+
24
namespace Atc.Test;
35

46
/// <summary>
@@ -83,20 +85,29 @@ public static async Task WaitForCall<T>(
8385
TimeSpan timeout = default)
8486
where T : class
8587
{
86-
var completion = new TaskCompletionSource<bool>();
87-
substitute
88-
.When(substituteCall)
89-
.Do(_ => completion.TrySetResult(true));
88+
try
89+
{
90+
substitute
91+
.ValidateCallReceived(
92+
substituteCall,
93+
MatchArgs.AsSpecifiedInCall);
94+
}
95+
catch (ReceivedCallsException)
96+
{
97+
var completion = new TaskCompletionSource<bool>();
98+
substitute
99+
.When(substituteCall)
100+
.Do(_ => completion.TrySetResult(true));
90101

91-
await completion
92-
.WaitForCompletion(timeout)
93-
.ConfigureAwait(false);
102+
await completion
103+
.WaitForCompletion(timeout)
104+
.ConfigureAwait(false);
94105

95-
substitute
96-
.ValidateCallReceived(
97-
substituteCall
98-
?? throw new ArgumentNullException(nameof(substituteCall)),
99-
MatchArgs.AsSpecifiedInCall);
106+
substitute
107+
.ValidateCallReceived(
108+
substituteCall,
109+
MatchArgs.AsSpecifiedInCall);
110+
}
100111
}
101112

102113
/// <summary>
@@ -114,19 +125,29 @@ public static async Task WaitForCall<T>(
114125
TimeSpan timeout = default)
115126
where T : class
116127
{
117-
var completion = new TaskCompletionSource<bool>();
118-
substitute
119-
.When(substituteCall)
120-
.Do(_ => completion.TrySetResult(true));
128+
try
129+
{
130+
substitute
131+
.ValidateCallReceived(
132+
x => substituteCall(x),
133+
MatchArgs.AsSpecifiedInCall);
134+
}
135+
catch (ReceivedCallsException)
136+
{
137+
var completion = new TaskCompletionSource<bool>();
138+
substitute
139+
.When(substituteCall)
140+
.Do(_ => completion.TrySetResult(true));
121141

122-
await completion
123-
.WaitForCompletion(timeout)
124-
.ConfigureAwait(false);
142+
await completion
143+
.WaitForCompletion(timeout)
144+
.ConfigureAwait(false);
125145

126-
substitute
127-
.ValidateCallReceived(
128-
x => substituteCall(x),
129-
MatchArgs.AsSpecifiedInCall);
146+
substitute
147+
.ValidateCallReceived(
148+
x => substituteCall(x),
149+
MatchArgs.AsSpecifiedInCall);
150+
}
130151
}
131152

132153
/// <summary>
@@ -139,26 +160,40 @@ await completion
139160
/// <param name="substituteCall">The call to wait for.</param>
140161
/// <param name="timeout">Timeout for the wait operation.</param>
141162
/// <returns>A task representing the async operation.</returns>
163+
[SuppressMessage(
164+
"Reliability",
165+
"CA2012:Use ValueTasks correctly",
166+
Justification = "Call should not be awaited for route to work")]
142167
public static async Task WaitForCall<TSubstitute, TResult>(
143168
this TSubstitute substitute,
144169
Func<TSubstitute, ValueTask<TResult>> substituteCall,
145170
TimeSpan timeout = default)
146171
where TSubstitute : class
147172
{
148-
var completion = new TaskCompletionSource<bool>();
149-
substitute
150-
.When(substituteCall)
151-
.Do(_ => completion.TrySetResult(true));
173+
try
174+
{
175+
substitute
176+
.ValidateCallReceived(
177+
x => substituteCall(x),
178+
MatchArgs.AsSpecifiedInCall);
179+
}
180+
catch (ReceivedCallsException)
181+
{
182+
var completion = new TaskCompletionSource<bool>();
183+
substitute
184+
.When(substituteCall)
185+
.Do(_ => completion.TrySetResult(true));
152186

153-
await completion
154-
.WaitForCompletion(timeout)
155-
.ConfigureAwait(false);
187+
await completion
188+
.WaitForCompletion(timeout)
189+
.ConfigureAwait(false);
156190

157-
substitute
158-
.ValidateCallReceived(
159-
async x => await substituteCall(x)
160-
.ConfigureAwait(false),
161-
MatchArgs.AsSpecifiedInCall);
191+
substitute
192+
.ValidateCallReceived(
193+
x => substituteCall(x)
194+
.ConfigureAwait(false),
195+
MatchArgs.AsSpecifiedInCall);
196+
}
162197
}
163198

164199
/// <summary>
@@ -176,20 +211,29 @@ public static async Task WaitForCallForAnyArgs<T>(
176211
TimeSpan timeout = default)
177212
where T : class
178213
{
179-
var completion = new TaskCompletionSource<bool>();
180-
substitute
181-
.WhenForAnyArgs(substituteCall)
182-
.Do(_ => completion.TrySetResult(true));
214+
try
215+
{
216+
substitute
217+
.ValidateCallReceived(
218+
substituteCall,
219+
MatchArgs.Any);
220+
}
221+
catch (ReceivedCallsException)
222+
{
223+
var completion = new TaskCompletionSource<bool>();
224+
substitute
225+
.WhenForAnyArgs(substituteCall)
226+
.Do(_ => completion.TrySetResult(true));
183227

184-
await completion
185-
.WaitForCompletion(timeout)
186-
.ConfigureAwait(false);
228+
await completion
229+
.WaitForCompletion(timeout)
230+
.ConfigureAwait(false);
187231

188-
substitute
189-
.ValidateCallReceived(
190-
substituteCall
191-
?? throw new ArgumentNullException(nameof(substituteCall)),
192-
MatchArgs.Any);
232+
substitute
233+
.ValidateCallReceived(
234+
substituteCall,
235+
MatchArgs.Any);
236+
}
193237
}
194238

195239
/// <summary>
@@ -207,19 +251,29 @@ public static async Task WaitForCallForAnyArgs<T>(
207251
TimeSpan timeout = default)
208252
where T : class
209253
{
210-
var completion = new TaskCompletionSource<bool>();
211-
substitute
212-
.WhenForAnyArgs(substituteCall)
213-
.Do(_ => completion.TrySetResult(true));
254+
try
255+
{
256+
substitute
257+
.ValidateCallReceived(
258+
x => substituteCall(x),
259+
MatchArgs.Any);
260+
}
261+
catch (ReceivedCallsException)
262+
{
263+
var completion = new TaskCompletionSource<bool>();
264+
substitute
265+
.WhenForAnyArgs(substituteCall)
266+
.Do(_ => completion.TrySetResult(true));
214267

215-
await completion
216-
.WaitForCompletion(timeout)
217-
.ConfigureAwait(false);
268+
await completion
269+
.WaitForCompletion(timeout)
270+
.ConfigureAwait(false);
218271

219-
substitute
220-
.ValidateCallReceived(
221-
x => substituteCall(x),
222-
MatchArgs.Any);
272+
substitute
273+
.ValidateCallReceived(
274+
x => substituteCall(x),
275+
MatchArgs.Any);
276+
}
223277
}
224278

225279
/// <summary>
@@ -232,26 +286,39 @@ await completion
232286
/// <param name="substituteCall">The call to wait for.</param>
233287
/// <param name="timeout">Timeout for the wait operation.</param>
234288
/// <returns>A task representing the async operation.</returns>
289+
[SuppressMessage(
290+
"Reliability",
291+
"CA2012:Use ValueTasks correctly",
292+
Justification = "Call should not be awaited for route to work")]
235293
public static async Task WaitForCallForAnyArgs<TSubstitute, TResult>(
236294
this TSubstitute substitute,
237295
Func<TSubstitute, ValueTask<TResult>> substituteCall,
238296
TimeSpan timeout = default)
239297
where TSubstitute : class
240298
{
241-
var completion = new TaskCompletionSource<bool>();
242-
substitute
243-
.WhenForAnyArgs(substituteCall)
244-
.Do(_ => completion.TrySetResult(true));
299+
try
300+
{
301+
substitute
302+
.ValidateCallReceived(
303+
x => substituteCall(x),
304+
MatchArgs.Any);
305+
}
306+
catch (ReceivedCallsException)
307+
{
308+
var completion = new TaskCompletionSource<bool>();
309+
substitute
310+
.WhenForAnyArgs(substituteCall)
311+
.Do(_ => completion.TrySetResult(true));
245312

246-
await completion
247-
.WaitForCompletion(timeout)
248-
.ConfigureAwait(false);
313+
await completion
314+
.WaitForCompletion(timeout)
315+
.ConfigureAwait(false);
249316

250-
substitute
251-
.ValidateCallReceived(
252-
async x => await substituteCall(x)
253-
.ConfigureAwait(false),
254-
MatchArgs.Any);
317+
substitute
318+
.ValidateCallReceived(
319+
x => substituteCall(x),
320+
MatchArgs.Any);
321+
}
255322
}
256323

257324
private static void ValidateCallReceived<T>(

version.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"$schema": "https://raw.githubusercontent.com/dotnet/Nerdbank.GitVersioning/master/src/NerdBank.GitVersioning/version.schema.json",
3-
"version": "1.0",
3+
"version": "1.1",
44
"cloudBuild": {
55
"buildNumber": {
66
"enabled": true

0 commit comments

Comments
 (0)