I am trying to use unit testing with XUnit for an ASP.NET v5 MVC v6 app. I can get simple unit testing on methods working. I would like to test Controllers. Right now, I have a HomeController with an Index action that returns the Home/Index view. I want to test that the Index view is the one that is returned.
Here is my current test file:
using Microsoft.AspNet.Mvc;
using Xunit;
using XUnitWithMvcSample.Controllers;
namespace XUnitWithMvcSample.Tests
{
public class Tests
{
private HomeController _homeController;
public Tests()
{
_homeController = new HomeController();
}
[Fact]
public void IndexActionReturnsIndexView()
{
var result = _homeController.Index() as ViewResult;
System.Console.WriteLine(result);
Assert.Equal("Index", result.ViewName);
}
}
}
Here's Controllers/HomeController.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
namespace XUnitWithMvcSample.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View();
}
}
}
When I run the test, it fails, since result.ViewName
is null. It looks like result
is just an empty ViewResult
with nothing to do with _homeController
. What do I need to do to get the test to find the Index view in HomeController?
Controllers should typically check the ModelState property before doing anything. In some ways, this is good. Validation is moved outside the action method, so you can test it independently of the controller action method.
When unit testing controller logic, only the contents of a single action are tested, not the behavior of its dependencies or of the framework itself. Set up unit tests of controller actions to focus on the controller's behavior. A controller unit test avoids scenarios such as filters, routing, and model binding.
XUnit vs. MSTest is concerned, the biggest difference between xUnit and the other two test frameworks (NUnit and MSTest) is that xUnit is much more extensible when compared to NUnit and MSTest. The [Fact] attribute is used instead of the [Test] attribute.
It sounds like you're trying to test functionality that's in the framework, rather than what's just in the method. All that's in the method is this:
return View();
So, literally, as long as a non-null ViewResult
is returned, then the method does what it's expected to do:
// Arrange
var controller = new HomeController();
// Act
var result = controller.Index() as ViewResult;
// Assert
Assert.IsNotNull(result);
Linking that result to a view is part of the ASP.NET MVC Framework and happens outside of that method. Which means that it's not part of the method call itself, but happens outside the scope of the method. That puts it outside the scope of the test.
You'd have to set up a kind of running ASP.NET MVC application and test that application in order to test that functionality, which is more of a black box test than a unit test.
It's a bit late answer but if you can change your action method like that, your test will work.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNet.Mvc;
namespace XUnitWithMvcSample.Controllers
{
public class HomeController : Controller
{
public IActionResult Index()
{
return View("Index");
}
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With