skip to the main content area of this page
Patterns and Practices

Using Rhino Mocks to Test the Model-View-Presenter Pattern in WCSF


In the past two posts:

I have been showing off parts of the PnPGuidance Administrative area and how it uses the Model View Presenter Pattern as well as a number of cool controls in the Web Client Software Factory, such as the RealTimeSearchMonitor Control and ObjectContainerDataSource Control.

The big advantage of using the Model View Presenter Pattern is that it allows us to better test the UI of an application without requiring us to be dependent on the ASP.NET runtime and IIS. Typically, one will mock the view, which is represented by an Interface, and test the interaction between the View Interface and the Presenter Class.

One could handcode mocks to represent the view, which is what you typically see with Microsoft Patterns & Practices Tests, or use a good mocking tool, such as Rhino Mocks that will dynamically create a mock view at runtime. Rhino Mocks will allow us to set expectations on the view and classes it collaborates with and we can tests to make sure those expectations are met by the application.

Let's use the following Posts Administration area that we discussed in the above 2 posts:

 

Rhino Mocks

 

where we have a View Interface Contract of:

 

public interface IViewPostsView

{

    string Filter { get; }

    int StartRow { get; }

    int MaxRows { get; }

    string SortExpression { get; }

 

    IList Posts { set; }

    int TotalRows { set; }

}

 

When the administrator changes the Filter in real-time or clicks on a Page Number in the Pager Area, the OnGetPosts Method of the Presenter Class is fired. The OnGetPosts Method calls the Blog Service and then returns the necessary information to the View.

 

public void OnGetPosts()

{

    int totalRows;

    View.Posts = _blogService.GetPosts(View.StartRow,

        View.MaxRows, View.Filter, View.SortExpression, out totalRows);

    View.TotalRows = totalRows;

}

 

Shown above is the reduced version with no exception handling just to keep things simple.

Given this information, we can now write tests to verify administrator expectations are met when changing the filter or clicking on the pager area.

One expectation is that when OnGetPosts is called by the view that the Posts Property on the View is set. Here is an example of using Rhino Mocks to mock the view and test the expectation:

 

[Test]
public void OnGetPostsShouldSetViewsPostsProperty()
{
    // Mock the View
    MockRepository mocks = new MockRepository();
    IViewPostsView view = mocks.DynamicMock<IViewPostsView>();
    
    // Create Presenter With Mock View and Dummy BlogService
    ViewPostsPresenter presenter = new ViewPostsPresenter(view, _dummyBlogService);
    
    // Set Expectations
    view.Posts = null;
    LastCall.IgnoreArguments();
    
    // Tell Rhino Mocks We're Done Setting Expectations
    mocks.ReplayAll();
    
    // Verify Expectations
    presenter.OnGetPosts();
    mocks.VerifyAll();
}

 

We could  write a test to verify the View's TotalRows Property is properly set as well.

 

[Test]
public void OnGetPostsShouldSetViewsTotalRowsProperty()
{
    // Mock the View
    MockRepository mocks = new MockRepository();
    IViewPostsView view = mocks.DynamicMock<IViewPostsView>();
    
    // Create Presenter With Mock View and Dummy BlogService
    ViewPostsPresenter presenter = new ViewPostsPresenter(view, _dummyBlogService);
    
    // Set Expectations
    view.TotalRows = null;
    LastCall.IgnoreArguments();
    
    // Tell Rhino Mocks We're Done Setting Expectations
    mocks.ReplayAll();
    
    // Verify Expectations
    presenter.OnGetPosts();
    mocks.VerifyAll();
}

 

You can also write tests that expose a bit about what the Presenter Class is doing internally. For example, we know from the code shown above that the Presenter's OnGetPosts Method calls the Blog Service's GetPosts Method and maybe we want to write a test that verifies that happens:

 

[Test]
public void OnGetPostsShouldCallBlogService()
{
    // Mock the View and  Blog Service
    MockRepository mocks = new MockRepository();
    IViewPostsView view = mocks.DynamicMock<ViewPostsView>();
    IBlogService mockBlogService = mocks.CreateMock<IBlogService>();
    
    // Create Presenter With Mock View and Mock BlogService
    ViewPostsPresenter presenter = new ViewPostsPresenter(view, mockBlogService);
    
    // Set Expectations
    Expect.Call(view.SortExpression).Return("PostID DESC");
    Expect.Call(view.Filter).Return(string.Empty);
    Expect.Call(view.StartRow).Return(1);
    Expect.Call(view.MaxRows).Return(25);
    int totalRows;
    Expect.Call(mockBlogService.GetPosts
            (1, 25, string.Empty, "PostId DESC", out totalRows)).Return(null);
    
    // Tell Rhino Mocks We're Done Setting Expectations
    mocks.ReplayAll();
    
    // Verify Expectations
    presenter.OnGetPosts();
    mocks.VerifyAll();
}

 

Hopefully the tests above give one a better understanding as to the usefulness of the Model-View-Presenter Pattern and a good mocking tool, like Rhino Mocks, to help test the expected behavior in the UI of your ASP.NET Web Applications.

There is a lot to learn about how any mocking tool works. Rhino Mocks has some good documenation on the web.


Tags: ModelViewPresenter, RhinoMocks


Topics



Popular Tags



Recent Links