Ok, I changed a few things around and got my unit test working.

Probably the biggest issue was that I was using Telerik JustMock Lite to do
my Mocking. It seems to not be able to handle asynchronous WebApi calls. I
commented out all the JustMock code, wrote a dummy repository, and now the
test is working. It's a pity.

Perhaps someone could suggest another Mocking library that doesn't have
this issue? (Does Moq handle async calls?)

So the final test looks like this: (and yes, I will go back and refactor
the name...eventually)

[Fact(DisplayName = "Calling the NextQuizQuestion api returns a
question")]public async void CallingNextQuizQuestionGetsAResult()
{
    //Arrange
    var triviaRepository = new DummyTriviaRepository();

    //Act
    UnitOfWork uow = new UnitOfWork(triviaRepository);
    TriviaController controller = new TriviaController(uow);

    var taskResult = await controller.Get();

    var result = Task.FromResult(taskResult).Result;

    //Assert
    Assert.IsType<OkNegotiatedContentResult<TriviaQuestion>>(result);
}


On Thu, Jul 23, 2015 at 6:27 PM, Tony Wright <[email protected]> wrote:

> I understand that point of view but that would mean that I would need two
> methods,  doesn't it? One to execute synchronously and the other calling
> that one via an asynchronous mechanism.
> On 23 Jul 2015 5:53 pm, "Greg Keogh" <[email protected]> wrote:
>
>> Just as an aside ... I gave up writing async unit tests years ago. After
>> jumping through hoops I realised that testing the code synchronously proves
>> that it works, then adding async testing just tests that the .NET
>> asynchronous infrastructure works (which I expect is does!). Maybe the test
>> harnesses are better at async testing now, but I generally avoid it except
>> for rare critical or fragile async points -- *Greg K*
>>
>> On 23 July 2015 at 17:28, Cormac Long <[email protected]> wrote:
>>
>>> Hi Tony,
>>>
>>> Change the return type of your test method to Task rather than void.
>>>
>>> Cheers,
>>> Cormac
>>>
>>> On Thu, Jul 23, 2015 at 2:42 PM, Tony Wright <[email protected]> wrote:
>>>
>>>> Hi all,
>>>>
>>>> I have been trying to unit test an async call in an MVC app and I can't
>>>> quite get it right.
>>>>
>>>> The application is an MVC app written in dot net.
>>>>
>>>> I am using xUnit to test the method, and Fluent Assertions to more
>>>> naturally describe the expected outcome (BDD).
>>>>
>>>> The test case is a Quiz application.
>>>>
>>>> Here is the test:
>>>>
>>>>  [Fact(DisplayName = "Calling the NextQuizQuestion api returns a 
>>>> question")]
>>>>  public async void CallingNextQuizQuestionGetsAResult()
>>>>  {
>>>>      //Arrange
>>>>      string userId = "[email protected]";
>>>>      var triviaRepository = Mock.Create<TriviaRepository>();
>>>>      Mock.Arrange(() => triviaRepository.NextQuestionAsync(userId))
>>>>          .Returns(() =>
>>>>              Task.FromResult(
>>>>                  new TriviaQuestion
>>>>                  {
>>>>                      Title = "When was .NET first released?",
>>>>                      Options = (new TriviaOption[]
>>>>                      {
>>>>                          new TriviaOption {Title = "2000", IsCorrect = 
>>>> false},
>>>>                          new TriviaOption {Title = "2001", IsCorrect = 
>>>> false},
>>>>                          new TriviaOption {Title = "2002", IsCorrect = 
>>>> true},
>>>>                          new TriviaOption {Title = "2003", IsCorrect = 
>>>> false}
>>>>                      }).ToList()
>>>>                  })
>>>>                  ).MustBeCalled();
>>>>
>>>>      //Act
>>>>      UnitOfWork uow = new UnitOfWork(triviaRepository);
>>>>      TriviaController controller = new TriviaController(uow);
>>>>
>>>>      var taskResult = await controller.Get();
>>>>
>>>>      var result = Task.FromResult(taskResult);
>>>>
>>>>      //Assert
>>>>      Assert.IsType<OkResult>(result.Result);
>>>>
>>>>  }
>>>>
>>>> The controller method that I am instantiating is:
>>>>
>>>> [ResponseType(typeof(TriviaQuestion))]public async Task<IHttpActionResult> 
>>>> Get()
>>>> {
>>>>     var userId = User.Identity.Name;
>>>>
>>>>     TriviaQuestion nextQuestion = await 
>>>> unitOfWork.TriviaRepository.NextQuestionAsync(userId);
>>>>
>>>>     if (nextQuestion == null)
>>>>     {
>>>>         return this.NotFound();
>>>>     }
>>>>
>>>>     return this.Ok(nextQuestion);
>>>> }
>>>>
>>>>
>>>> The test crashes on the line
>>>>
>>>> var taskResult = await controller.Get();
>>>>
>>>> due to a timeout.
>>>>
>>>> The issue here I believe is that the test is single threaded and it
>>>> never returns from the call because it doesn't have a synchronisation
>>>> context to return to.
>>>>
>>>> Does anyone know how I can get this test to work?
>>>>
>>>> Regards,
>>>> Tony
>>>>
>>>
>>>
>>

Reply via email to