Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mocking Async Task

Tags:

c#

.net

moq

I have the following situation in my unit tests using Moq on .NET 4.0 using Microsoft BCL

Task<MyClass> mockTask = new Task<MyClass>(() => new MyClass());

uploadHelper.Setup().Returns(mockTask);

Task.WaitAll(mockTask);

The problem that I am facing is that Task.WaitAll(mockTask) simply blocks and never returns.

What am I doing wrong here?

Edit Note that mockTask is async here in my context.

like image 805
Chubsdad Avatar asked Feb 20 '14 08:02

Chubsdad


2 Answers

Your task is not started !

Just use:

 Task<MyClass> mockTask = Task.FromResult(new MyClass());

Alternatively, this works as well:

Task<MyClass> mockTask = new Task<MyClass>(() => new MyClass());
mockTask.Start();
like image 162
Olivier Avatar answered Sep 21 '22 03:09

Olivier


The proposed solutions have one problem - the task may be over by the time Returns is called. That means your unit test exhibits a different async semantics than your real code. Is that what you want?

If you truly want to capture the async nature of the tested code you must not use the Returns method with a value.

Instead use the Returns overload accepting a function. Something like this:

uploadHelper.Setup().Returns(() => Task.Run(() => new MyClass()));

That way you can be certain to exercise async execution path.

like image 43
mark Avatar answered Sep 21 '22 03:09

mark