6

How do I functional test a .net mvc controller/action.

I just came from many years of Rails development into a gig where I'm hacking on .net mvc. It hurts but I'm hoping that a large part of this is just the learning curve.

What's not immediately obvious to me is an analog for Rails functional and integration testing in the .NET world. Rails makes functional testing so obvious and simple that you'd be foolish not to take the time to get coverage in place. With .NET - I've yet to get Google to yield a single result that seems worthwhile. I'm hoping it's my nascent .net status that's just keeping me from entering the right search terms or missing some paradigm.

HELP!

pnuts
  • 58,317
  • 11
  • 87
  • 139
Cory
  • 2,538
  • 2
  • 18
  • 19
  • A controller action is simply a method and can be tested as such (using faking/mocking for isolation). Is there anything more in particular to functional testing than the Arrange, Act, Assert pattern for each condition and providing the concrete instances of classes to prevent isolation and testing the entire application? – StuperUser Jul 12 '11 at 17:22
  • 2
    Part of the reason may be terminology. In the Rails world we talk about functional tests, but we really mean unit tests for our controllers. From what I've seen most Rails programmers mix true unit tests (testing code only) and functional tests (including external dependencies such as a database) together. The .NET community seems to follow those more closely. Roy Osherove has a decent book on testing in .NET http://artofunittesting.com/ – Wizard of Ogz Jul 12 '11 at 18:23

3 Answers3

3

Forgive me for my lack of knowledge of Rails, and for telling you what you already know about rails, but I hope to put things in a comparison format for other users.

Rails has 3 types of tests Unit, Functional, and Integration.

Unit Tests test your Models

Functional Tests for your Controllers

Integration Tests for testing the Flow between Controller Actions

This paradigm seems to be taught from the beginning with rails.

However in the .NET MVC world the methods of testing aren't laid out like they are in Rails.

Many developers will write Unit Tests on their controllers in the way you write a Unit Test on your Models in rails. You basically call a method (Controller Action) and get an object back from the method. You can then assert it has the values you expect. Doing this is a pain in the butt because you have to mock so much crap (HttpContext etc). Plus, it isn't a functional test. You are only testing the one method as opposed to testing the functionality of the application.

In Rails you aren't writing a Unit Test on your controller, you are actually making a web request and you get a web response. You can check the status code, cookies, etc. You are testing the system from end to end.

There are a few ways you can do this in .NET MVC

1) Steven Sanderson has a little tool to help with this.

http://blog.stevensanderson.com/2009/06/11/integration-testing-your-aspnet-mvc-application/

When I first saw this and started using it I thought it was awesome, but I ran into problems.

2) RestSharp + NUnit - This is my current preference for doing these kinds of tests. It allows you to put a web request together and get a response pretty easy. With a few generic methods you can move pretty fast with restsharp. NUnit will give you the assertions you need. I just make the request against my local IIS server and assert the different items I expect in the response. You won't really be able to test which model is assigned to the view like you can in rails but that hasn't been a problem for me.

If you are used to RSpec then you can get SpecFlow which should similar.

Rails builds testing right into the framework and it is a first class citizen. Its too bad it isn't this way in .NET MVC.

Hope that helps.

Brett Allred
  • 3,459
  • 26
  • 30
0

The best way to unit test MVC application is to add a new Unit Test Project inside the solution. Just right click on the project solution, click on add then add -> test project.

You will see a test class which will have methods having [TestMethod] attribute on top of them. You will be writing your unit testing logic in these methods.

Inside the test project add new reference .dll of the MVC project on which the unit testing is to be carried out. This will enable the test project to discover the actual controller actions of the main project.

Add a reference to System.Web.MVC namespace.

Please refer to a sample of a test method below:

[TestMethod]
public void DisplayCustomer()
{
   CustomerController obj = new CustomerController();
   var testResult = obj.DisplayCustomer();
   Assert.AreEqual("DisplayCustomer",testResult.ViewName);
}

Build and run the project to see pass/failed tests in the Test Results window

Hope this helps !

Thanks.

Sushrut Kanetkar
  • 363
  • 3
  • 13
0

If you truly want to test functionality, as opposed to standard "unit" testing, you have a few choices.

  1. Get creative and use MS test to set up more function based tests.
  2. use a BDD type of framework (specFlow?)
  3. use a more functional test framework, like Selenium

If you are aiming the function testing towards more automated UAT, you also have items like the FIT Framework (and Fitnesse).

Are these a direct analog to the tooling and frameworks in Rails? No, but .NET is not Rails.

Gregory A Beamer
  • 16,870
  • 3
  • 25
  • 32
  • Right - understand that it's apples and oranges. The real question should have read: "What's the proper way to functionally test an mvc controller/action". Didn't know if there was a prescribed pattern or if it was open-ended. I suppose I'm looking for the .NET noob functional-testing beginners guide. – Cory Jul 12 '11 at 17:32
  • @Cory, see my comment on the original post regarding "unit testing" and "functional testing" terminology. I also recommended a book :) – Wizard of Ogz Jul 12 '11 at 18:24