I believe Moq does handle async calls but never tried it myself
On Fri, Jul 24, 2015 at 9:00 AM, Tony Wright <[email protected]> wrote:
> 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
>>>>>
>>>>
>>>>
>>>
>