0

I'm unit testing my viewmodel command that call a web service. My viewmodel has a dependency on IHttpService which 'GetAsync' method is called by this viewmodel.

I want to unit test my viewmodel and manage the fact that 'GetAsync' returns a cancelled task, which is the case when it's implemented with HttpClient and when an TimeOutException occurs. How can i setup my IHttpServiceMock to return such a task ?

I tryed with TaskCompletionSource.SetCanceled() but i'm not able to tell with which exception it was cancelled...

Loul G.
  • 997
  • 13
  • 27
  • A timeout exception wouldn't cause the task to be cancelled, it would cause the task to complete in a faulted state. Being cancelled means that it willing stopped executing due to a request from a `CancellationTokenSource`. – CodingGorilla Nov 05 '14 at 20:42
  • Ok, so i have configured the mock setup to return a task created like this: `CancellationTokenSource cts = new CancellationTokenSource(200); Task t = new Task(() => { throw new TimeoutException("timeout"); }, cts.Token);` But this task in my 'onCancelled' continuation doesn't contain any exception... – Loul G. Nov 05 '14 at 20:55
  • You are not understanding, an exception *does not cancel the task*, it **completes** the task in the faulted state. – CodingGorilla Nov 06 '14 at 00:34

1 Answers1

1

I think you need to use SetException instead of SetCanceled; a thread that completes with an exception still completed, vs. a thread that was asked to stop working.

Andy
  • 8,432
  • 6
  • 38
  • 76
  • Sorry but SetException is not making the task cancelled, but faulted. – Loul G. Nov 05 '14 at 21:22
  • @LoulG. I don't think you can have canceled with an exception; the states look like they are mutually exclusive. – Andy Nov 06 '14 at 00:30
  • 1
    @Andy You are correct, I tried explaining that in my comment on the question. Cancellation is an entirely separate condition from Faulted, which is caused by *any* exception being thrown during the task execution. – CodingGorilla Nov 06 '14 at 00:35
  • @Andy You were right, getting a task canceled specifying an exception is not possible as they are mutually exclusive. In order to mimic the behaviour of HttpClient timeout, i had to return a task's TaskCompletionSource with exception set to `new TaskCanceledException()` and handle it into an OnlyOnFaulted task continuation. As a side note about HttpClient timeout, one can read [this](http://stackoverflow.com/a/19822695/1303737) – Loul G. Nov 06 '14 at 21:22