Asp.Net MVC without ‘The framework’ Part 2: a good example of Unit Testing
This article is probably a good example of unit testing a web app. Not some example about testing if switches statement, but real testing scenarios that one would come across when testing a web application
Part 1 we ave covered how to implement ASP.Net MVC on the webform. We’re making use of the pattern Model View Presenter/Supervising Controller pattern.
In this part 2 we’re going to cover how to test a Controller(which from this point on will be referrred to as the Presenter).
To test the Presenter class, we’re going to rely heavily on Inversion of Control technique. In general, we want to inject all the dependencies that a Presenter should have. We
replace this dependencies with a bunch of special objects. We then verify whether the Presenter is behaving as expected, by asking it to these special objects.
Let’s go into an example to make sense of it.
public class Presenter
{
private IView view;
public Presenter(IView view) {this.view = view}
public ListAll()
{
var repository = new CarRepository();
view.Cars = repository.FindAll();
}
}
So above, we have a presenter class with ListAll() method that’s responsible of retreiving all the available cars. Afterwich the presenter passes it on to the View.
Let’s have alook at the View.
public interface IView
{
IList Cars { set;}
}
public class ListingPage : System.Web.UI.Page, IView
{
private Presenter presenter;
public ListingPage()
{
presenter = new Presenter(this);
}
public void Page_Load()
{
presenter.ListAll();
}
public IList Cars
{
set
{
someRepeater.DataSource = value;
someRepeater.DataBind();
}
}
}
So the view instantiate the Presenter, hook up the page_load event to the presenter.ListAll() call, which in turn going to populate someRepeater with a list of cars. Simple enough right? (if you’re not sure why this is, revise Part 1). The problem of testing the Presenter class here is the fact that is so tiedly bound with the Repository class. The repository class probably calls the database and creates a collection of cars. It doesn’t seem possibly to test the Presenter without accessing the database. This is where the Inversion of Control technique comes in to save the day.
Let’s overload the Presenter constructor so that it’s also accepts any types that implements the same FindAll method call.
public class Presenter
{
private IView view;
private ICarRepository repository;
public Presenter (IView view) : this(view, new CarRepository)
public Presenter (IView view, ICarRepository repository)
{
this.view = view;
this.repository = repository;
}
}

expose the dependency so that we can inject mocks later on
With the change that we made above, we can start doing this:
[Test]
public class PresenterTest
{
public void Presenter_FetchDataFromRepository_BindItToView
{
// set up all the dependencies so that we can assert whether
// certain method and properties get called properly by
// the presenter
IView view = generateSpecialView();
ICarRepository carRepository = generateSpecialkCarRepository();
// set up the system under test (SUT)
var Presenter = new Presenter(view, carRepository);
// run the method
presenter.ListAll()
// assert that the presenter is doing stuff to these
// special objects that we created, as expected
// so 2 questions that we want to ask is;
// Assert.IsTrue ( is the CarRepository.FindAll method
// Called by the presenter )
// Assert.IsTrue ( does the view gets binded by
// the return value of the car repository )
}
}
The aim here is to test if the Presenter doing the right interactivity with its dependencies. In our case here, the carRepository.FindAll() is called, and the result is being passed to the view. If the 2 asserts on the dependencies passed, then we have successfully test the Presenter.
To put it simply:
It’s like bringing in a sparrinng partner to know whether a boxer have trained enough
![]()

Easier said than done. How do you do this type of assertion? So here I’m relying on a mocking framework. One of the most popular mocking framework is RhinoMocks written by a guy whose work I admire: Oren Eini (Ayende Rahien). This is the syntax that RhinoMocks uses, which obviously differ depending on the mocking framework you use.
[Test]
public class PresenterTest
{
public void Presenter_FetchDataFromRepository_BindItToView
{
// this is something that Rhino Mocks use to create mocks.
// potentially can be put in the test's contructor if it's
// going to be reused
// between test methods
Mocker mockRepository = new Mocker();
IView mockView = mockRepository.Create();
ICarRepository mockCarRepository =
DynamicMock.Create();
using (mockRepository.Record(0))
{
// here we setup all the expectations on the dependencies
// for e.g we expect the carRepository.
// Find all to get called and return something
IList something = new List() { new Car(1), new Car(2) };
Expect.Call(() => carRepository.FindAll())
.Return(something)
.Message("CarRepository.FindAll() isn't called");
// we also expect the view to be binded with the
// same 'something'
Expect.Call(() => view.Cars)
.SetPropertyWithArguments(something)
.Message("View isn't binded with the result set");
}
//now set the system under test (SUT)
using(mockRepository.Playback())
{
// set up the system under test (SUT)
var Presenter = new Presenter(view, carRepository);
// run the method
presenter.ListAll()
}
}
}
So above, I’ve created a couple of RhinoMock objects and set up the expectation. Afterwhich, I set it to playback mode, where at the end, it’ll run through all the expectations and check whether they have been satisfied. Assertion will fail if they’re not met. Pretty cool huh? You can also notice that I’ve used different methods to assert method and property calls.
Obviously I have throwned alot here. Let’s recap:
- To make it testable: All Presenter’s dependencies needs be injectable throught the constructor.
- To test it: Inject the presenter with Mock dependencies, and ask the expected behavior to these mock objects.
About this entry
You’re currently reading “Asp.Net MVC without ‘The framework’ Part 2: a good example of Unit Testing,” an entry on Ronald Widha
- Published:
- 22.03.09 / 9am
- Category:
- Articles

Comments
Jump to comment form | comments rss [?] | trackback uri [?]