Note that there are some explanatory texts on larger screens.

plurals
  1. POWhat are the possible problems with unit testing ASP.NET MVC code in the following way?
    primarykey
    data
    text
    <p>I've been looking at the way unit testing is done in <a href="https://github.com/NuGet/NuGetGallery/blob/master/Facts/Services/MessageServiceFacts.cs" rel="nofollow">the NuGetGallery</a>. I observed that when controllers are tested, service classes are mocked. This makes sense to me because while testing the controller logic, I didn't want to be worried about the architectural layers below. After using this approach for a while, I noticed how often I was running around fixing my mocks all over my controller tests when my service classes changed. To solve this problem, without consulting people that are smarter than me, I started writing tests like this (don't worry, I haven't gotten that far):</p> <pre><code>public class PersonController : Controller { private readonly LESRepository _repository; public PersonController(LESRepository repository) { _repository = repository; } public ActionResult Index(int id) { var model = _repository.GetAll&lt;Person&gt;() .FirstOrDefault(x =&gt; x.Id == id); var viewModel = new VMPerson(model); return View(viewModel); } } public class PersonControllerTests { public void can_get_person() { var person = _helper.CreatePerson(username: "John"); var controller = new PersonController(_repository); controller.FakeOutContext(); var result = (ViewResult)controller.Index(person.Id); var model = (VMPerson)result.Model; Assert.IsTrue(model.Person.Username == "John"); } } </code></pre> <p>I guess this would be integration testing because I am using a real database (I'd prefer an inmemory one). I begin my test by putting data in my database (each test runs in a transaction and is rolled back when the test completes). Then I call my controller and I really don't care how it retrieves the data from the database (via a repository or service class) just that the Model to be sent to the view must have the record I put into the database aka my assertion. The cool thing about this approach is that a lot of times I can continue to add more layers of complexity without having to change my controller tests:</p> <pre><code>public class PersonController : Controller { private readonly LESRepository _repository; private readonly PersonService _personService; public PersonController(LESRepository repository) { _repository = repository; _personService = new PersonService(_repository); } public ActionResult Index(int id) { var model = _personService.GetActivePerson(id); if(model == null) return PersonNotFoundResult(); var viewModel = new VMPerson(model); return View(viewModel); } } </code></pre> <p>Now I realize I didn't create an interface for my PersonService and pass it into the constructor of my controller. The reason is 1) I don't plan to mock my PersonService and 2) I didn't feel I needed to inject my dependency since my PersonController for now only needs to depend on one type of PersonService.</p> <p>I'm new at unit testing and I'm always happy to be shown that I'm wrong. Please point out why the way I'm testng my controllers could be a really bad idea (besides the obvious increase in the time my tests will take to run). </p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload