posts - 234, comments - 480, trackbacks - 56

My Links

News




I am born in Bangladesh and currently live in Melbourne, Australia. I am a co-founder and core developer of Pageflakes www.pageflakes.com and CEO at Simplexhub, a highly experienced software development company based in Melbourne Australia and Dhaka, Bangladesh.

I also created SmartCodeGenerator

Some of my articles
Flexible and Plugin based .Net Application..
Mass Emailing Functionality with C#, .NET 2.0, and Microsoft® SQL Server 2005 Service Broker'
Write your own Code Generator or Template Engine in .NET
Smart Code Generator .NET: Usage Overview
Smart Code Generator .NET: Architectural Overview
Smart Code Generator .NET: using with NAnt and Cassini

Archives

Free Programming Language Training

ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

Recently I have started playing with the Moq (pronounced "Mock-you" or just "Mock") a Mocking Library for .NET Developers, that takes full advantage of .NET 3.5 (i.e. Linq expression trees) and C# 3.0 features. Here in this post I will discuss how I have used the TryUpdateModel method in the Form POST scenario and also share how I have written a test case using Moq mocking library to deal with the TryUpdateModel<TModel>(TModel model) method of the ASP.NET MVC controller.

I have a very simple user interface, that allows user to  enter data and submit, to add a new "User".
 

My View Page is:


and my "Action" is

   
You may have already noticed that I have decorated my action without any parameters, and my POST related codes are executed by checking the request type.

if (Request.RequestType == POST)
{
  //code
}

As I have no parameters in my CreateUser(), I did not need to create separate action  with AcceptVerbs("GET") and AcceptVert("POST") attribute. I have created an empty instance of MembershipCreateViewModel object and passed it to the TryUpdateModel() method to get the values of the posted form into my viewmodel object. MVC framework takes care of the rest and populates the viewModel with the desired values. Also note the RedirectToAction() method has been on success, it is  very important to perform this client - redirect. It will ensure that  the form does not resubmit, and the user will never see a prompt like this, if he hits the browser refresh button.

  

My MembershipCreateViewModel class is as follows,


  

I did not prefer passing four parameters to my CreateUser() Action such as,

[AcceptVerbs["POST"])
CreateUser(string username, string email, string password, string confirmPassword)
{
//code
}

instead I kept the method simple by using the MembershipCreateUserViewModel to communicated between the Controller and the View.

This is all good, but by now you may be wondering how would I test this Controller>Action. Lets explore that part. Here I will demonstrate my TestCase using the Moq framework, but you can do the same using other popular mocking frameworks like Rhino Mock, NMock, NMock2, NUnit.Mocks, EasyMock, TypeMock etc, or even with plain vanilla C# code. First of all I will need a FakeHttpContext to interact with my Controller from the test environment.

It is very straight forward to create a mock of a class or interface in Moq, I have created mocks of HttpContextBase, HttpRequestBase, HttpResponseBase, HttpSessionStateBase, HttpServerUtility above and decorated methods and properties that I use in my test cases using the Setup and SetupGet method that is available in the Moq library. 

Note how easily with couple of lines of code I have a mockup of the HttpContextBase. The Mock<T> allows creation of custom value matchers that can be used on setups and verification, completely replacing the built-in It class with our own argument matching rules. 

var httpContext = new Mock<HttpContextBase>();
var request = new Mock<HttpRequestBase>
httpContext.Setup(ctx => ctx.Request(request.Object);

This above code snippet is creating mock instances of HttpContexBase and HttpRequestBase classes, and then also setting up that httpContext.Request will return the mock instance "request".

Now lets look at how I have used this mock httpContext in a test case.

  
I have created a test case here that tests our CreateUser() action. Note I have created an instance of the ControllerContext and passed the httpContext mock object as a parameter of its constructor. After that I have assigned this instance ( context ) to the controller.ControllerContext property.

The Mock.Get() method is interesting it can retrieve a mock object for the given object instance. Here I have retrieved the request object and have modified it further. I have setup so that the request.Form returns NameValueCollection. You may be wondering why did I pass NamValueCollection. You may recall that I have used the TryUpdateModel() method in my action to get the form values into our viewmodel, and if you look what is happening under the hood of TryUpdateModel() method you will find that, "Form" is of type System.Collections.Specialized.NameValueCollection and a member of System.Web.HttpRequestBase, and

the internals of TryUpdateModel() iterates through each item of the ContollerContext.HttpContext.Request.Form object and populates the matching properties of the viewmodel using reflection. The above code snippet from the ValueProviderDictionary class where we see that the keys are being read from the Form object to populate a dictionary.

Conclusion

Here in this post I have discussed a Form POST scenario and I have decorated my action method without any parameters as by default TryUpdateModel method looks at the submitted Form object and attempt to assign it to the viewmodel object that we pass. I have also demonstrated how I have used the Moq library to create fake/mock objects for my testcases, how I have setup some fake methods and properties. I have also demonstrated the handy Mock.Get method that can retrieve a mock object from a given object instance and allows us to modify the mock object further. Thank you for being with me so far and I hope this helps.

Print | posted on Saturday, May 16, 2009 12:10 AM |

Feedback

Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq


Nice article, very helpful.
Thanks!!!

nike air
9/7/2009 11:18 PM | klecike
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

Nice article, very helpful.
Thanks!!!
9/8/2009 4:17 PM | العاب تلبيس
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

very very nice :)
9/13/2009 5:01 AM | مسلسل ام البنات
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

.thanks for sharing your views..

Regards,
9/19/2009 12:07 AM | Free online games
Gravatar

#  ASP.NET MVC Tips

I have also demonstrated how I have used the Moq library to create fake/mock objects for my testcases, how I have setup some fake methods and properties. I have also demonstrated the handy Mock.Get method that can retrieve a mock object from a given object instance and allows us to modify the mock object further
Thanks for sharing your views…
9/19/2009 3:40 PM | Free online games
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

The Mock.Get() method is interesting it can retrieve a mock object for the given object instance. Here I have retrieved the request object and have modified it further. I have setup so that the request
9/19/2009 3:41 PM | etf trading
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

I have setup some fake methods and properties. I have also demonstrated the handy Mock.Get method that can retrieve a mock object from a given object instance and allows us to modify the mock object further.
9/23/2009 4:02 AM | Government Grants
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

well,this is a pretty good site.demo is good and the method which you are following is good..thanks for great info.
regards,
9/30/2009 6:12 PM | TimeshareDEPOT
Gravatar

# re: ASP.NET MVC Tips: Form POST, TryUpdateModel, unit test, Moq

This is all good, but by now you may be wondering how would I test this Controller>Action. Lets explore that part. Here I will demonstrate my TestCase using the Moq framework, but you can do the same using other popular mocking frameworks like Rhino Mock, NMock, NMock2, NUnit.Mocks, EasyMock, TypeMock etc, or even with plain vanilla C# code. First of all I will need a FakeHttpContext to interact with my Controller from the test environment.
10/21/2009 12:59 AM | nike shoes new
Post A Comment
Title:
Name:
Email:
Website:
Comment:
Verification:
 
 

Powered by: