In a previous post “Fluent async testing,” I introduced a sample library to beautify unit tests relying on Task-based assertions. Tests for this type of library typically make heavy use of “canned Tasks” to ensure every case is handled correctly. There are four common cases representing the most often observable states of Task:
- Pending completion
- Completed successfully
- Completed with exception(s)
- Canceled
(Technically there are two variants of each state above, one for Task
with no result and one for Task<T>
.)
Writing boilerplate code to manufacture all these Tasks in every test method becomes tedious pretty fast, so I almost always extract each one into a central method I can reuse. For FluentSample, I put the code in TaskResultBuilder. The pattern used here actually has a name: “Object Mother”.
In .NET 4.5, the “object grandmother” for Task is TaskCompletionSource<T>
. For example, this is how you can get a Task representing an exception:
TaskCompletionSource<bool> tcs = new TaskCompletionSource<bool>(); tcs.SetException(new InvalidOperationException("This is expected!")); return tcs.Task;
Incidentally, .NET 4.6 reduces the boilerplate even further with Task.FromException
and Task.FromCanceled
.
Thanks, pfxteam!