ASP.NET MVC – Mock Membership for Controller Test - asp.net-mvc

I’m not sure how to mock an ASP.NET Membership for my controller test.
Controller Code:
MembershipUser username = Membership.GetUser();
string UserID = username.UserName.ToString();
Does anyone know how to mock this for a controller test? I'm using RhinoMocks.

I've started working on something like this. Rather than doing a true mock, I created a FakeMembershipProvider that just implements the minimum of MembershipProvider that I need and provides a way to set the users and such. I'm doing the same for RoleProvider. Then I've set the App.config for my test project so it uses these as the providers.
So far, it seems to be working well.

I would watch the MVS StoreFront Serieshttp://www.asp.net/learn/mvc-videos/
For one on Mocking -
http://www.asp.net/learn/mvc-videos/video-365.aspx
And the Membership one
http://www.asp.net/learn/mvc-videos/video-372.aspx
One for Membership and the view of refactor with OpenID
http://www.asp.net/learn/mvc-videos/video-425.aspx

To mock the objects connectected with Membership static class, you should use its Abstract classes in that case, for mocking the GetUser() method, use MembershipProvider class, it is possible to mock, just pass it to your controller and it's done.
Good luck, if you'll have any problems, just let me now, I'll post up some code examples.

Related

Common functionality across multiple ASP.NET MVC controllers

I'm working on ASP.NET MVC application & have a quick design question for you.
So I need to implement a common functionality for all my controllers (well, most of them).
I don't want to repeat the same logic in all the controllers.
What'd be the ideal approach in the best interest of MVC?
I found people saying create base controller and inherit it in your controllers. But when I visualize a controller, I can see it'd contain only action methods that return some content/views - Correct me if I'm wrong.
OneController
{
ActionMethod A1
{
//Code to return list of objects for the given integer value. So it calls database stored procedure.
}
}
...multiple such controllers are there.
I'd still like to have A1 exists in the OneController, just put its logic somewhere common place.
Also some people suggest to create just plain Helper class to place the common method.
Could you please suggest me what approach will be better (Or any other appropriate approach)? Thanks.
I agree with you that, most of the times, it only makes sense to inherit from base controllers when we're talking about Actions or methods that are really related. But of course, you can just use base controllers for everything. Your choice.
Other than that, you have 2 options. For classes that have little to no chance of being polymorphic (change behavior depending on the implementation), you are fine to create static classes and just use them inside your controllers. An example would be a class that does math calculations, these are not that polymorphic by nature.
For all the other cases, I'd strongly suggest that you use dependency injection. One of the reasons being that unit testing will become way easier. Here's a guide on how to do it for MVC 4 onwards using the built in engine: https://www.asp.net/mvc/overview/older-versions/hands-on-labs/aspnet-mvc-4-dependency-injection. If you don't want to use it and use Ninject or Simple Injector, you can implement your own ControllerActivator and use Ninject, for instance, to get an instance of your controller.
When using dependency injector, normally your controller would get the dependencies in the constructor, like this:
public class StoreController : Controller
{
private IStoreService service;
public StoreController(IStoreService service)
{
// service in an injected dependency
this.service = service;
}
}
For more information, Google ASP.NET dependency injection.

Custom roles architecture in ASP.NET MVC 5, Dependency Injection issues

I've got an architecture issue that I'm hoping someone can be of assistance to guide me in a more ideal strategy. The way I've been forced to do this reeks of "code smell".
I've got two different kinds of "Roles". I've got the built in Identity Roles, and I've got a custom set of roles (User Group Roles). I store these User Group Roles in a database, essentially a relationship between a user id, a usergroup role id, and a usergroup id. I'm using Ninject for dependency injection of my UserGroupService that handles all the CRUD operations of assigning users with certain usergroup roles to usergroups.
My first plan of attack was to create a custom authorization attribute that I could place on actions, similar to the Identity [Authorize(Role="")] attribute. I did not have any luck with this because I cannot inject a service into an attribute class (needs a parameterless constructor).
After that didn't work, my second plan of attack was to write an extension method for IPrincipal, essentially mimicking User.IsInRole("") with User.IsInUserGroupRole(""). This didn't work because I cannot inject a service into a static class.
Currently I am stuck including some booleans in the model of every view that has role based logic involved. So for instance:
public ActionResult Navigation()
{
var isSystemAdmin = User.IsInRole("Administrator");
var isUserGroupAdmin = _userGroupService.IsUserGroupAdmin(User.Identity.GetUserId()) && !isSystemAdmin;
var isGeneralUser = !isSystemAdmin && !isUserGroupAdmin;
var model = new NavigationViewModel
{
IsSystemAdmin = isSystemAdmin,
IsUserGroupAdmin = isUserGroupAdmin,
IsGeneralUser = isGeneralUser
};
return PartialView("_Navigation", model);
}
The issue here is that I have to do this any time I want to determine what kind of roles the user is currently in. It works, but it smells.
Am I missing something here? I think the most ideal option would be the extension method strategy of being able to call it right off of User, but cannot seem to make that work.
Constructor DI is not the only way to get access to a dependency.
Each IOC has a way of resolving a dependency, all you need is a reference to the IOC container. So, even if your attribute requires a parameterless constructor you could still resolve the dependency manually.
Something like this should help :
http://www.c-sharpcorner.com/UploadFile/47fc0a/resolving-dependency-using-ninject/
Is it a great way to use your IOC this way? Probably not but it sure beats what you're doing now.

Unit Testing Claims in .Net MVC app

Background : We are using MVC4 and using WIF for Claims/Authorization. We are using Moq/MvcContrib for Mockup Objects. I have looked here and created the MockIdentity and MockPrincipal Objects - do I need them?
Goal : I have a controller class that has a class level attribute that only allows users with 'Manager' claim to access the actions. I want to create mock users and test to see if anyone that doesn't have 'Manager' claim can access the actions or not.
I get the mock concept but I have only dealt with the data objects mocking and having a tough time figuring out what plugins/classes/methods/setups I need in place to do what I need to do.
Thanks in advance.
I want to create mock users and test to see if anyone that doesn't have 'Manager' claim can access the actions or not.
No, you don't. You just want to pass users to that attribute you wrote and test that sets the filterContext.Result correctly. That's it. You don't need to test that System.Web.Mvc works. Single unit under test!
Presumably your attribute is an AuthorizeAttribute, correct? So you need to test OnAuthorization(AuthorizationContext).
Disclaimer: I haven't used moq in a while, but your code would presumably look generally like this:
var user = new Mock<IPrincipal>();
user.Setup(/* whatever you need to look at */);
var authContext = new Mock<AuthorizationContext>();
authContext.Setup(ac => ac.HttpContext.User).Returns(user);
var myAttribute = new RequireManagerAttribute();
myAttribute.OnAuthorization(authContext);
authContext.VerifySet(ac => ac.Result = /* whatever you expect */);

Testing model validation without testing implementation

What's the best way of going about testing model validation without making assumptions on the implementation details of the validation (eg. DataAnnotations).
For example, if I have a Customer model object that has a Firstname property, I want to test that binding a missing value for the Firstname property will result in a validation error but I don't want to test how validation his been implemented. That is, I don't want to use DataAnotations.Validate.
I've seen several, differing, opinions on this floating around and haven't found one that I agree with.
I ended up writing a helper method that wraps ModelValidator and returns IEnumerable<ModelValidationResult>. It requires that MVC be configured with your validation provider of choice, but it means that test code need not change when your validation implementation does:
public static IEnumerable<ModelValidationResult> Validate<TModel>(TModel model)
{
var modelMetadata = ModelMetadata.FromLambdaExpression(r => r,
new ViewDataDictionary<TModel>(model));
ModelValidator validator = ModelValidator.GetModelValidator(
modelMetadata, new ControllerContext());
return validator.Validate(model);
}
This will depend on the framework you are using for validating your models. So what you are asking is not possible without taking this into account. ASP.NET MVC by default uses a data annotations model provider which invokes the validation rules for data annotations and if you want to test this you will need to do a DataAnnotations.Validate in your unit tests or verify that your model is decorated with the proper attributes.
Personally I use FluentValidation.NET which provides an elegant way for unit testing my validators so it is not much of a hassle.

How do I unit test controllers for an asp.net mvc site that uses StructureMap and NHibernate?

I have an asp.net mvc2 application that is using StructureMap 2.6 and NHibernate 3.x. I would like to add unit tests to the application but am sort of at a loss for how to accomplish it.
Say I have a basic controller called Posts that has an action called Index. The controller looks something like:
public class PostsController : Controller {
private readonly IPostService _postService;
public PostsController(IPostService postService) {
_postService = postService;
}
public ActionResult Index() {
return View(_postService.QueryOver<Post>().Future());
}
}
If I wanted to create an nunit test that would verify that the index action is returning all of the posts, how do I go about that? If mocking is recommended, do you just assume that interaction with the database will work?
Sorry for asking such a broad question, but my web searches haven't turned up anything decent for how to unit test asp.net mvc actions that use StructureMap (or any other IOC) and NHibernate.
btw, if you don't like that I return a QueryOver object from my post service, pretend it is an IQueryable object. I'm using it essentially in the same way.
I would refactor your query into the service layer itself. My reason for suggesting this is that you can then have all your security, projections, paging, filtering, etc in one spot. Even if you don't have these concerns now, it will be much easier to add them in later if everything is not strewn about in different controller actions.
With this split up you can easily unit test the GetAllPosts() method. (Either mock out your repo or just plug into an in memory database.) As far as testing the controller action, it's basically a service call at this point so would you gain any benefit from testing it? In my opinion, probably not.
// service
public IQueryable<Post> GetAllPosts()
{
return postRepository.QueryOver<Post>().Future();
}
// controller
public ActionResult Index() {
return View(_postService.GetAllPosts());
}
To unit test your controller action you must mock your service, as it is a external process that are beyond the scope of the unit being tested.
But no, you don't have to assume that your service will just work. You should write integration tests that will ensure that your service works properly.
The unit test will give you coverage on the behavior of the Controller and the integration test on the behavior of the service. Once you got both covered you are fine.

Resources