Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test for MVC 5 async Task<ActionResult> Index view

I am new to unit testing. Not sure what to do my testing on, I went ahead and started one with an Index view on ClientController. I am having issues writing test method for the Index view which is declared as async Task. What i want to do is make sure this action returns data. Not sure how important this test is but I wanted to learn ways to write tests in MVC 5. Seems to have trouble writing tests for the view that are async.

ManagementService class

public IQueryable<Client> GetAllClients(bool includeDeleted = false)
    {
        var query = context.Clients.AsQueryable();
        if (!includeDeleted) query = query.Where(c => !c.IsDeleted);
        return query;
    }

Client Controller

public ClientController(IApplicationContext appContext, IManagementService adminService, IDomainService domainService)
    {
        this.adminService = adminService;
        this.appContext = appContext;
        this.domainService = domainService;
    }
public async Task<ActionResult> Index()
    {
        var clients = adminService.GetAllClients();
        return View(await clients.ToListAsync());
    }

//TEST

[TestMethod]
    public void Index()
    {
        //Arrange
        var mgmtmockContext = new Mock<IManagementService>();
        List<Client> db = new List<Client>();
        db.Add(new Client { ClientId = 1, Name = "Test Client 1" });
        db.Add(new Client { ClientId = 2, Name = "Test Client 2" });
        mgmtmockContext
            .Setup(m => m.GetAllClients(false))
            .Returns(() => { return db.AsQueryable(); });

        //Act
        ClientController controller = new ClientController(null, mgmtmockContext.Object, null);

        var result = controller.Index() as Task<ActionResult>;

        //Assert
        Assert.IsNotNull(result);
    }

After I create an instance of the controller, I am not sure how to pass the mock object to Index() so I can test this view returns data.

What I want to Assert is Assert.AreEqual(2, result.Count()) so I can run this test.

like image 895
bladerunner Avatar asked Apr 28 '14 22:04

bladerunner


1 Answers

In order to get the list out of the result you need to do two things:

  1. Get the actual result from the task
  2. Get the model out of the action result

Here's how you do this:

    var result = controller.Index() as Task<ViewResult>;

   // Get the actual result from the task
    var viewresult = result.Result;

    // Get the model from the viewresult and cast it to the correct type 
    // (notice in the first line I changed ActionResult to ViewResult to make sure we can access the model.
    var model = (List<Client>)(viewresult.Model);

    //Assert
    Assert.IsNotNull(result);
    Assert.AreEqual(2, model.Count);
like image 57
Kenneth Avatar answered Oct 08 '22 19:10

Kenneth