Showing posts with label controller. Show all posts
Showing posts with label controller. Show all posts

Saturday, August 13, 2011

Integrating Spring.net with MVC3

If you are doing any kind of serious project, you sure want to use some sort of dependency injection.

Why do I need dependency injection?

Lot's of people have written lot's about why dependency injection is required.  I am not going to repeat all that, just a few points that I think, cannot be ignored

  • Configuration flexibility - alternative implementations of a given service can be used without recompiling code
  • Testability - Since we can provide alternative implementation of any given service at any time, any class can be unit tested very easily and effectively.  Its easy to inject a fack implementation of a service in the class we want to unit test
  • Reduction of Boiler plate code - Since we no longer need to create instances of classes and inject them with proper dependencies
  • Promotes loose coupling between classes and subsystems - Since classes are not dependent on a specific implementation, they are dependent on the contract that the other classes expose.
Enough said about dependency injection.  At this point if you are still not convinced that you need dependency injection, then I strongly recommend reading the full series of posts on Dependency Injection from Fabien Potencier here

Alright, so we need dependency injection, what next?

How do we implement dependency injection?  Should we hand code the logic and create our own way of doing dependency injection?

Well, take my advice, never ever, never every do that!  Always look for options, you will surely find one depdendency injection framework/container that suites your requirements.  Even if it does not fit your requirement completely, I am sure the framework/container provides enough hooks, based on which you can customize it to you taste!
In the year 2011 and beyond, you cannot be serious if you are wasting your time and someone Else's money writing a dependency injection framework (I know a few people who have done that, can you believe it!)

What is Spring.NET?

Spring.NET is an awesome dependency injection framework (actually its lot more than that).  Its open-source and its design is based on the proven Java based Spring Framework.  The breath of functionality in Spring .NET spans application tiers which allows you to treat it as a "one stop shop" but that is not required.  The best thing about Spring .NET is, its not an all-or-nothing solution.  You can use the functionality in its modules independently.  Spring.NET integrates with a lot of other projects like NHibernate, NUnit, Active MQ, Quartz .NET, Velocity etc.


Enough about Spring.NET, if you want to know more details about Spring.NET, I strongly recommend visiting this site, it has all the info you need.  It has links to the latest documentation, blogs, articles, faq's etc.

By this time we agree that, we should use a dependency injection framework and for the sake of this post, I am going to show how easily we can integrate the Spring.NET dependency injection framework in our MVC3 application.  Lets not waste any more time and jump into the code straightaway to get this part started, shall we!


How do they do it?

To Integrate Spring.NET into the MVC3 application you will need to do the following steps
  • Add the Spring.NET dependencies to the project.
  • Make the web.cofig changes to register the spring context
  • Declare the dependencies in an xml file
  • Write the code to interact with the dependencies in the HomeController
  • Inherit the Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication
Lets have a look at each step one after the other.

Add the spring.net dependencies to the project

For integrating Spring.NET in your MVC3 application you will need to add references of following Spring.NET assemblies.
  • Spring.Core.dll
  • Spring.Web.dll
  • Spring.Web.Mvc.dll
These dll's can be found in the downloaded Spring.NET zip package from this link.

Make the web.config changes to register the spring context

In this step we add a <configSection> for the Spring.NET configuration.  In the spring config section we would like to register the spring context.  Update web.config should look like

What we are doing here is, telling Spring.NET to look for a file called web.xml inside the Config directory.

What will the web.xml file contain?  

It will contain the dependency injection configurations for the classes in our application. 

Declare the dependencies in an xml file

Spring will search for a file named web.xml inside the Config directory, directly under the root of you application.  Lets make sure, Spring finds the file.  Create a directory called Config at the root level of your MVC3 application and create a file called web.xml inside it.  The project structure should look somewhat like this

Project Structure with web.xml included in the project
Now, its time to register our dependencies in the web.xml.  We are going to add a very simple dependency of IAccountService that will give us total number of users in the system.  The web.xml would look like this

The web.xml is just a plain XML file that uses Spring.NET xml schema to inject the AccountService into the HomeController. We have given an id to the HomeController its Home in our case. We are also declaring that HomeController has a property Called AccountService. This property will be auto injected by the Spring.NET container with the reference of type AccountService.

Notice that the HomeController is not a singleton class.  MVC3 framework creates a new instance of the Controller every time a request comes for that controller.  Hence, Spring needs to know that, the HomeController is not supposed to be a singleton class.  This is done by adding the attribute singleton="false" in the declaration of the HomeController.

The next declaration in the web.xml is that of AccountService.  For the sake of this example this class has no dependencies.  For our example this class is going to be very simple it will return some hard coded values.

Notice that the singleton attribute has not be specified for the declaration of AccountService.  By default the singleton value is true, this means that the AccountService is a singleton class.  Spring.NET will  instantiate only one instance of the AccountService for the entire application!

Write the code to interact with the dependencies in the HomeController

As seen in Step - 2, HomeController is going to have a property of type AccountService.  We are going to query the AccountService to get the user count which will be eventually be shown on the UI.

As you can see there is no magic in our classs. HomeController simply calls the AccountService to get the UserCount and sets the value in the ViewBag. The AccountService implementation is extremely simple, it returns a hardcoded value of 5454.

Lets look at the view SpringIndex.cshtml that will show the UserCount from the ViewBag.

As you must have guessed, the view could not have been any simpler. It simply shows the message with the UserCount in it.

Inherit the Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication

We are almost done with all the plumbing required to integrate Spring.NET with MVC3 but, one last thing is left.  We need to inherit our Global class in the Global.asax.cs file from Spring.Web.Mvc.SpringMvcApplication instead of System.Web.HttpApplication.  This is required so that Spring registers the controller factory to instantiate the Controllers when the request comes.  This is done so that Spring gets an opportunity to dependency inject the controllers.

And we are done! Lets run the application and browse the URL /Home/SpringIndex to see what happens. If you have followed the post till this point, browsing the url will result in a page like this
SpringIndex renders with UserCount value
The User count 5454 is coming from the AccountService which we successfully injected into the HomeController.

When the request for SpringIndex action of the HomeController comes to the server  following things occur
  • Spring intercepts the call and instantiates HomeController 
  • Injects all the dependencies of HomeController i.e. AccountService in our case
  • Calls the action method SpringIndex to complete the request
  • SpringIndex method calls the AccountService to get the UserCount and sets it in the ViewBag
  • SpringIndex.cshtml is rendered which shows UserCout!
We have successfully integrated Spring.NET with a MVC3 application!  That's all folks!

Tuesday, May 4, 2010

How to mock static methods using PowerMock

OK, what are we up to today!  Today I will demonstrate how can we write unit test for a class that invokes a static method on another class to get some work done using PowerMocks (Mockito api) - Mocks on steroids! 

Yeah, Yeah I know, I know implementing functionality using static methods is bad and stuff like that.  But sometimes you just can't help it as its not in your control.  Hence, as all wise man (woman included) say, better deal with it!

We have not yet seen how we could mock normal classes and interface and directly looking at how to mock static methods.  Well as Mr. IronMan said

Sometimes you gotta run before you can walk.

Currently, I am working on a project that uses Spring Roo.  Roo uses a lot of AspetJ goodness.  It adds a lot of static methods to domain objects via AspectJ, making the domain objects richer.  For e.g. In a domain Class Customer it would add methods like findCustomer, findAllCustomers, countCustomers etc.  If you are interested in exploring more about Spring Roo, start here.

Spring Roo uses Spring MVC as the web layer.  Hence, I am going to take example of CustomerController (a controller that does CRUD on Customer domain object).  Enough history, lets see the real stuff!

Requirement:

When user requests to see the customer information, CustomerController should find the requested Customer and return that in the model.

Controller Code:

The controller code would look like

Not showing the Spring MVC specific annotations.  Here, findCustomer is the method added by Spring Roo to the Customer domain class.  This is a static method which  is invoked by CustomerController to get the requested Customer instance.  This is what we want to test. 

How will we test it - How do they do it!:

As I explained in my previous post, PowerMocks uses custom class-loader and byte-code manipulation to enable mocking of static methods.  PowerMocks does this by using the following annotations
  • @RunWith -- PowerMocks uses a custom Runner called PowerMockRunner.  This is done so that 
    • PowerMocks could show informative message if an exception is thrown from the test
    • PowerMocks could notify listeners of certain events.  For e.g. before the test methods start executing an event BeforeTestMethod is triggered.  Don't worry, if you don't understand this.  Its a little advanced stuff.  Just remember, that we need to use a Custom runner.
  • @PrepareForTest -- This annotation tells PowerMock to prepare certain classes for testing. Classes needed to be defined using this annotation are typically those that needs to be byte-code manipulated. This includes final classes, classes with final, private, static or native methods that should be mocked
That's about all the annotations you will need!  Next we will have to tell PowerMocks that we want to mock static methods of which class.  This is done using

We are saying PowerMocks (using the Mockito extension api) that we want to mock static methods in Customer class.

Next up, we have to stub the method we are interested in (we will be doing state based testing.  PowerMocks also supports interaction based testing, using the verify syntax.  Will not be showing it in this post though).  That's done like this

And then we can simply assert the customer is returned in the modelMap.  That's all!  Here's the complete test case code.

And we are done!  As we can see, PowerMocks (using the Mockito extension api) uses English like syntax, because of this test cases look a lot compact and are easier to read.

As usual, feedback, comments and complaints are always welcome!

Monday, April 26, 2010

How to use the mocks to verify behaviour in grails

As you can probably see, I am completely vella (word in Hindi which means jobless) today!  Have set a personal record of posting so many blogs in a single day!

Based on the feedback i have received, here's another post in the how-to series.  This one shows you how to create mocks, on which expectations could be set and finally verify that all expectations were satisfied.

For the sake of this post as well I will use our very old PersonController.

Lets take the example of my good old friend, YES the PersonController

Yes, you are right I am actually in love with PersonController :)

What are we testing - What are we upto today!:

PersonController will invoke save method on the PersonService to actually save the person.  We want to verify this behavior.

Controller Code:

Here's how the controller code looks like

We are specifically interested in mocking the personService.save() method.  Have already explained how to test rest of the code in my previous posts here and here.

How will we test it - How do they do it!:

GrailsUnitTestCase class provides a superb method call mockFor (to create mock objects!)  How simple is that!  Using mockFor method we could create mocks for any class.  We could set expectations on the mock and finally verify that all expectations are met.

The test case steps to tests the above code.
  1. Mock the PersonService using the mockFor method
  2. Set expectations on the PersonService
  3. Dependency inject the mocked personService into the controller instance.
  4. Invoke the controller code
  5. Verify all the expectations are met
Thats all.  Pretty easy ha!   
   
Test code looks like this:

Yes, that's all!  As we can see, grails adds extremely flexible and powerful mocking support.  Use it!

As usual feedback, comments and complaints are welcome!

Sunday, April 25, 2010

How to stub message method in a controller

Hello Gang!  Based on the feedback from all you guys, here's a post about how easily can we stub the message method while writing controller Unit tests.

Lets take the example of my good old friend, YES the PersonController

Requirement:

After saving a person user should be redirected to show view, with a flash message indicating user was saved successfully.

Controller Code:
We have seen similar code in the past lets look at it again

We are not interested in code showing the action required if errors are returned while saving a person (As we had already covered that here)

Only different between the earlier code and this one is the flash.message and the use of message method.

How will we test it - How do they do it!:

In the grails environment, a method called message is dynamically added to the instance of PersonController, but how do we write a unit test for this?

All our controller test cases have been extending ControllerUnitTestCase which adds a lot of utility methods and fields to the controller instance.  But unfortunately it does not stub out the message method.  Hence, to test the above code we will have to stub out the message method manually. How? remember metaClass technique from my earlier post we will apply it here as well.

  1. Stub out the save method (on the person instance ) to return true, using the metaClass of Person
  2. Add a dummy message method on the controller instance, again using the metaClass of controller
  3. Assert that flash.message was correctly set by the PersonController 
  4. Remember to remove the metaClass of Person using which we stubbed the save method using the GroovySystem class.  (For explanation on why is this necessary see this post)
   
Test code looks like this:

If you notice we didn't use removeMetaClass for the controller instance. Why? because our test case extends ControllerUnitTestCase which creates a new instance of the controller class under test (in this case PersonController)before every test case is run. And hence we don't bother to use the removeMetaClass for the controller instance.

That's all folks!  As we can see metaClass is a real boon for unit testing

As uaual feedback, comments and complaints are welcome as always!

Unit testing Grails Controller - Part - 3

Alright folks this is the third and final installment of Unit Testing Grails Controller series.

In the last post I explained how we could write a test case where controller returns a model that could be used by view to render itself.

In this post we will see how we could write tests for situations in which controller has to render a view (may be to show validation errors while saving a instance of domain class)

Tired of repeating, but will say it again anyways, taking an example of a controller that performs CRUD on Person domain class lets call it PersonController

Requirement:

If an error occurs while saving a person, controller should re-render the create view showing the error so that user can rectify the error and try again.

Controller Code:
The controller code that will do the job for us looks like

How will we test it - How do they do it!:

Again, in the grails environment, save method on a person instance will actually fire an insert statement, but do we really want to do that while writing a unit test for PersonController?  The right answer is NO.  10 Points if you get that right!

So what are we doing in the above code sample.
  1. Creating a person instance using the request parameters
  2. Try to save the person created in the previous step
  3. If save fails render the create view and return from there (Guard clause is an import pattern which deserves a post for itself)
  4. If save succeeds redirect user to show view.
We should have a unit-test, for each of the above steps.
We already know how to write test case for step 4 from the first post

Lets focus on the first three steps.  There are two ways in which we can test the above code.  A longer and a shorter way!  And yes you guessed it, I will show the longer way first :)

Method 1: 
  1. use mockDomain(Person) to add the save dynamic method to person instance
  2. From the test code, we could populate the params map with invalid values
  3. Those params would be used to construct the Person instance
  4. While saving the person instance constraints will be fired, which will fail because of invalid values
  5. This will cause the save method to return false and hence if condition will be satisfied causing the render to execute.
  6. ControllerUnitTestCase class provides us a convenient property called modelAndView using which we can assert that controller actually renders to the create view
The test class code to demonstrate the above method is as follows

Although we should have written another test case to assert that the model was correctly populate by the controller but for the sake of this blog I have shown the assert in single test case.

Now that you have the Grails power, don't go anywhere!  I promise, will not bore you for long.  Here's the Method 2 of testing the above code.

Method 2:
  1. Stub out the save method (on the person instance) to return false manually, using the metaClass of Person
  2. use the modelAndView property to assert that controller actually renders the create view
  3. Remember to remove the metaClass using which we stubbed the save method using the GroovySystem class.  If you don't do this then the metaClass setting will interfere with other tests that use the save method.  Because of this, some test cases could misteriously start failing when, run along with other tests and pass when run individually.  Such a situation is extremely difficult to debug and fix.  This is the single most common mistake people do while using metaClass.  Take my advice, Dont do it!
Short and simple isn't it.  lets look at the test code.

See its pretty easy to randomly add/stub methods using the metaClass.  Its a really powerful tool but as Spider Man's uncle Ben once said
With great power comes great responsibility!
use it responsibly!

Here, I conclude the three part series to demonstrate art of Unit Testing the grails controller. 

I hope you liked reading it as much as I liked writing it.  Feedback, Comments and Complaints are welcome as always!

Unit testing Grails Controller - Part - 2

As promised to my readers here's the second installment of Unit testing grails controller.

In my previous post  we had seen how can we test a situation where grails controller redirects user to a different action.

In the post we will focus on how we could test a situation where controller returns a model, which can be used by a view to render itself.

Again, as in the previous post for simplicity I am taking an example of a controller that performs CRUD on Person domain class lets call it PersonController

Requirement:
When user tries to view person's data,  controller should retrieve requested person's information and return it so that view can render itself.

Controller Code:
The controller code would look like

For simplicity I have not shown the code to handle a situations when person with the given id is not found.

How will we test it - How do they do it!:
Clearly, when above code is run in the Grails environment Person.get(personId) will actually fire a database query to get the person.  But when we are unit testing the controller we dont want to fire a database query.  Basically we want to test the PersonController in isolation.

Fortunately, grails provides a method called mockDomain.  This is an extremely powerful method added by the GrailsUnitTestCase class.  As the name suggests, it mock's any grails domain class (as simple as that :)).  This method adds dynamic methods such as save, get, various finder's etc. to Grails domain class.  For e.g. 

will add previously mentioned dynamic methods to Person class.  Which effectively means that we can simulate the behaviour of these methods without actually firing queries agains our database.  Which is what we wanted in the first place!

There are two overloaded versions of mockDomain method
 

This version behaves as if there are no records in the Person table. 

Second version is

This version behaves as if, each person instance found in the [List of people] represents one record in the person table.  Hence when you call Person.get(123) if the list contained a person with id 123, that person will be returned.

Enough Said!  Show me the code damn it!


The Test case class:
The test case can be written as
 

Thats all folks!  This is all we need to tests the controller method.

Stay tuned for next installment of Unit Testing Grails Controller!

In this post I have changed my style a little.  Explanation comes before the actual code.  Do give me feedback about this approach which one do you like and why?

Tuesday, April 13, 2010

Unit testing Grails Controller - Part - 1

Recently I have been experimenting a lot with grails.

One most import language/framework feature that attracts me is "how easily can we right good unit tests".  As the quality of unit tests will in turn determine the quality of production code.  

Hence, here's my attempt to explain how one can write good Grails Controller tests.

In a grails controller mostly we would be doing any of the following things
Today I am going to cover the first scenario i.e. "Redirect a user to a different action" and we will see how easy it is to write its Unit test case.

For simplicity I am taking an example of a controller that performs CRUD on Person domain object lets call it PersonController

Requirement:    
Whenever user tries to view the index action on PersonController he should be redirected to list action (which shows the list of people)

Controller Code:
Controller code that does the job for us is as follows

Test case class:
Grails Testing Plugin provides excellent support to test controller methods.  Unit test for the above method could be written as follows

Explanation:
Grails is a framework that makes heavily use of Convention over Configuration.  This principal is applied to unit test cases as well.  There are a few things special about the above unit test case.
  • Name of the test case PersonControllerTests
    • This means that the name of controller class under test is PersonController.
    • Although we could have named the test class anything and explicitly mention the controller class under test is PersonController.  However, I am not going to show how that's done in this post as I want to keep this post as simple as possible.
  •  It extends from ControllerUnitTestCase 
    • This automatically initializes controller property of the ControllerUnitTestCase.  This property will be initialized with an instance of PersonController class.
    • Base class also adds dummy dynamic methods like "render" and "redirect" to the PersonController class.  These methods are usually available only in Grails environment
    • Base class also adds members like "params", "redirectArgs", "flash", "modelAndView" etc. to the controller instance
    • Base class tearDown method removes the dummy dynamic render and redirect methods from the PersonController class.
The index action of PersonController class simply redirects the user to list action.

As explained earlier the base class ControllerUnitTestCase adds dummy dynamic redirect method to the PersonController class.  The dummy redirect method simply inserts all arguments passed as key value pairs in the redirectArgs map.  redirectArgs is a Map member property added by ControllerUnitTestCase to the PersonController.

Hence the statement that asserts "index action redirect to list action" would look like

We can easily make out that writing good Unit test is extremely easy in  Grails.  We did not have to deal with mocked HTTP requests or responses to test the redirect behavior. 

In next blogs I would show how easily we could write unit tests for the following

As usual your feedback/comments are highly appreciated.
Have some Fun!