Rajesh Pillai

My experiments with asp.net mvc, jquery, wpf, silverlight, sharepoint, tdd and design patterns.

  Home  |   Contact  |   Syndication    |   Login
  43 Posts | 2 Stories | 36 Comments | 0 Trackbacks

News

Twitter












Tag Cloud


Article Categories

Archives

Post Categories

business

MVP in Action - Unit Test

This is in continuation to the article geekswithblogs.net/rajeshpillai/archive/2009/11/29/mvp1.aspx.  This post will deal with
writing simple unit test case for the "User" user creation use case we covered in the above blog post.  For some quick benefits of unit test
please refer my earlier post geekswithblogs.net/rajeshpillai/archive/2009/11/28/some-notes-from-my-tdd-session.aspx

Background

Unit testing means testing a piece of code or a method.  White unit testing we need to stub or fake out external dependencies
so that the test can run in isolation.  The following two test cases we will cover

  1. When saving a user with valid data should display "Successfully submitted the user." message on the view.
  2. When saving a user with empty name should display "<ul><li>user:User name cannot be empty</li></ul>" the
    following message on the view.

Let's proceed with writing the test cases.  We will be using the "Rhino Mock" mocking framework to mock our views.  Rhono mock is availabe at ayende.com/
 

1.  Test Case 1 :

The name of the method should indicate the "action" and the "expected result".  Let's dig line by line to understand the test case. I have used MSTest.  You
can use your preferred unit testing framework.  Basically we are following the "AAA" paradigm.  It stands for "Arrange->Act->Assert".  This is just a convention
but would be quite handy to follow.


The first thing we do is "Arrange" our objects.  We mock the IUserView using RhinoMocks GenerateMock() method.
Mocking allows you to set expectations on the object.  We need to also stub the view in this case so that the appropriate "User" object can be created.

Line 72 to 75 sets the stubbed value on the view.  Then we set the expectation on the "Message" property on the view.  Next
comes the "act" part.  We do this by invoking the method on the presenter which we intend to test.  And the assert is done
by calling the "VerifyAllExpectations" method on the view.  When you mock a view using RhinoMock additional extension
methods are available on the mocked object.  "VerifyAllExpectations" is one of them.  If our expecation is correctly verified
the test passes.  Let's see the result in action.


You can see the the test passes.   Let's get on to the second test case.

2.  Test Case 2 :

 Let's execute the test and see the result.

We pass the name as "empty string" and the test works as expected.  You can experiment with the test.  The simplicity of this test shouldn' dicourage you.  They may be a life saver where you have many integration points where different
teams are working on different modules and you want to ensure that your code is working as expected.  If any other
piece of code changes it should be easy to detect rather than going through the entire sanity test again. 

Here is the presenter code.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Web.ViewContracts;
using Demo.Service;
using Demo.Service.Messages;
using Demo.Objects.Entity;
using System.Text;

/// <summary>
/// Summary description for UserPresenter
/// </summary>
///

namespace Web.Presenter
{
    public class UserPresenter
    {
        IUserView view;
        IUserService userService;

        public UserPresenter(IView userView)
        {
            view = userView as IUserView;
            userService = new UserService();
        }

        public void Save()
        {
            User user = new User();
            user.Email = view.Email;
            user.IsActive = view.IsActive;
            user.Password = view.Password;
            user.UserName = view.UserName;

            UserResponse userResponse = userService.Save(user);

            if (userResponse.Status == ServiceStatus.Success)
            {
                view.Message = userResponse.Message;
            }
            else
            {
                StringBuilder sb = new StringBuilder(100);
                sb.Append("<ul>");
                foreach (ErrorInfo error in userResponse.Errors)
                {
                    sb.Append("<li>" + error.key + ":" + error.message +  "</li>");
                }
                sb.Append("</ul>");

                view.Message = sb.ToString();
            }
        }
    }
}

The presenter code is kept simple for demonstration purpose.

Hope you enjoyed this post.  As best practice you can move out the "hardcoded" values from the test into some constants or config. Watch out for this series as I will post examples of more complex scenarios and its real life implications. 

Happing Testing !!!

 

posted on Monday, November 30, 2009 4:50 PM

Feedback

# re: MVP in Action - Unit Test 2/13/2011 6:35 AM Naresh Kumar
Hi Rajesh good post what I was looking for, I am pretty new to MVP pattern, so I would like to know if having business objects in view is a good practice or the elements for business object

interface view
{
int RollNumber { get; set;}
string StudentName { get; set;}
string Standard { get; set;}
}

or

interface view
{
student Student{ get; set;}

}



Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification: