When developing simple validation logic in Asp.Net Mvc you can use the built in validators. One of them is the RegularExpression Validator. I had a simple scenario with a property of DateTime type called StartDate. Validation format (yyyy-mm-dd). It should be a simple task , but details are always messy.
I created a simple pattern and tested it with various examples in one of the Regex Editors.
To check if this solution works , two unit tests were created. First implementation of tests used the Regex class , but then I found out that you can use Attribute classes inside your code. I changed tests and used the RegularExpressionAttribute class inside test. Those tests are better because , with Regex our , we are checking if regex pattern is correct. With Attribute class used inside the test , we are testing actual scenario that is happening inside our app .
Here are the tests.
Yey green light, They passed so it’s working ! I tested the app and … validation was always incorrect . First thought , my pattern is incorrect. But , it is working inside RegEx Editor so I it has to be correct.
It seems that when DateTime object is passed to the RegExpAttribute , something weird is happening and validation fails. I have simulated this scenario with simple test.
Maybe it’s the problem with the type of the object. This test converts DateTime object to string fail.
Then I realized that .ToString() , method by default creates string including the hh-mm-ss. In my scenario those parameters were initialized with zeros My simple regex pattern wont match this string. Correctly formatted string passes the Test.
It’s time to look inside the RegularExpressionAttribute. Let me “Reflect” or “DotPeek” that for you.
Here is the code inside the class.
The Highlighted part is the problem. .IsValid() method uses default.ToString(). DateTime is parsed to the string with hh-mm-ss and that’s the root of the problem.
There is a simple solution to this problem. You just need to attach DisplayFormat.
– “green light” in test doesn’t mean that your code is working .
– create tests on “real” data
– try simulate environment and context as much as possible. To many assumptions and your test isn’t testing real scenario. In my case , I used the string inside test when my app used DateTime object.
Some of the actions that we are writing in Asp.Net MVC contains logic which uses data from the User context eg. user authentication or user name. Controller base class contains User property which is the instance of IPrincipal with two important properties.
The IPrincipal is taken from the HttpContext
So if your action is using the User property directly (you can always wrap this property inside a class that implements mockable Interface ) there is a problem with unit testing. In a isolated enviroment like test case , Controller doesn’t have the HttpContext. It is an external dependency.
HttpContext is retrieved from the ControllerContext
In order to fake the User property First we need to create a fake ControllerContext. To create it we need HttpContext which also needs HttpRequest. User is created from IPrincipal and IIdentity , with those classes we can create a Stub inside the HttpContext.
Yep , It’s quite complicated. Fortunately MvcContrib Library helps a little by providing classes that are faking IIdentity and IPrincipal
If you want to create a fake user you just need to write
When creating FakeIdentity userName parametr is really important. If you want ,not authenticated user , pass Empty String as a parameter
Yey , it’s the end ! Check out this simple graph.
Using this information , I have implemented simple TestHelper with methods to generate Fake ControlleContext with faked User.
Hope this sample helps.
As a part of my thesis , I am creating web app in Asp.net MVC. I m using NHibernate , NUnit , RhinoMocks , WCF , Ninject , Glimpse and also Elmah . This is a quite big project with a lot of unit tests. I am treating it as a playground.
Create entity action scenario in my app is simple. First there is a get action which builds View and prepares model. Then this newly created model (filled with values from the view) is passed to action with [HttpPost] attribute. It is a good practice to if ModelState.IsValid before performing any DB operations.
I have a lot of tests testing controllers and their action. In this case on of the tests should check behaviour of the controller when the ModelState.IsValid value is false. I have tried different approaches : trying to mock controller , trying to mock its context , inspecting code with dotPeek (cool decompiler from the JetBrains) wasn’t helpfull. Then I realized that you can do something like this.
As you can see , I am modifying ModelState by injecting fake data that will result in IsValid property set to false.
In Asp.Net MVC you can attach various attributes to the controllers actions. One of them is Authorize which is used to managed access.
In this example every time user runs the Index action Authorize class performs :
- Check if user is in list of users in the Authorize User parameter.
- you can set usernames parameter
- role check looks like this
In my scenario I have database with all the data required for the membership provider on another server. Simple methods like ValidateUser are on the wire. Default Authorize class uses the user.IsInRole which needs “local” role provider . With DB behind the service layer it won’t work at all. I have launched ILSpy and made a little research.
It appears that Authorize Attribute is not sealed and you can extend its behaviors. Mehods inside class are marked as virtual so you can easily override them.
So here is my implementation of Authorize class over WCV. Most important part is the call service.IsUserInroles(name). Service through WCF check the roles and return boolean value.
Method used in my service