Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Testing an async method in ASP MVC Controller with Nunit

I have an ASP.NET MVC application, with an Controller that features asynchronous methods, returning Task<PartialViewResult> object and marked with the async keyword. This method only takes the data from the database in async mode.

public async Task<PartialViewResult> SomeMethod()
{
    using (var unitOfWork = _factory.Create())
    {
        var result = await unitOfWork.SomeRepository.GetAsync();

        return PartialView(result);
    };
}

During testing, the stream just freeze in this spot (At run time this code works well):

var models = await unitOfWork.SomeRepository.GetAsync();

This is my test for this method:

public void GetExchange_GetView_OkModelIsViewModel()
{ 
    //fake Repository returns fake Data from DB
    var mockSomeRepository = new Mock<ISomeRepository>();
    mockSomeRepository.Setup(x => x.GetAsync(...).Returns(new Task<List<SomeType>>(() => new List<SomeType>()));

    //fake UoW returns fake Repository
    var mockUnitOfWork = new Mock<IUnitOfWork>();
    mockUnitOfWork.Setup(x => x.SomeRepository).Returns(mockSomeRepository.Object);

    //fake factory create fake UoW
    var fakeUnitOfWorkFactory = new Mock<UnitOfWorkFactory>();
    fakeUnitOfWorkFactory.Setup(x => x.Create()).Returns(mockUnitOfWork.Object);

    //Our controller
    var controller = new SomeController(fakeUnitOfWorkFactory);

    //Our async method
    var result = controller.SomeMethod();
    result.Wait();

    //---Assert--
}

Question: why is the stream in my method freezes during test execution???

UPDATE

This test begins to work if I replace

var result = await unitOfWork.SomeRepository.GetAsync(); 

to

var models = unitOfWork.SomeRepository.GetAsync();
models.Start();
models.Wait();
var result = models.Result;

But I don't quite understand why it works like that. Can someone explain?

like image 543
Titov S.P. Avatar asked Dec 19 '25 00:12

Titov S.P.


1 Answers

When testing an async method your test method should be async as well. NUnit can handle this without issue.

[Test]
public async Task GetExchange_GetView_OkModelIsViewModel() {
    // ...

    var controller = new SomeController(fakeUnitOfWorkFactory);
    var result = await controller.SomeMethod(); // call using await

    // ...
}
like image 182
Igor Avatar answered Dec 20 '25 14:12

Igor