asp.net mvc 3 - How can I unit test an AuthorizeWhereIn attribute with Ninject -
i'm using custom authorisation attribute (blatantly plagiarised answer) have hit hurdle can't find way unit test it. unfortunately need unit test @ same time invoke controller action i'm trying find way ninject dependency injection in unit test.
the authorizewherein attribute is:
public class authorizewherein : authorizeattribute { /// <summary> /// add allowed roles property. /// </summary> public new hciroles roles; /// <summary> /// checks see if user authenticated , has /// correct role access particular view. /// </summary> /// <param name="httpcontext"></param> /// <returns></returns> protected override bool authorizecore(httpcontextbase httpcontext) { if (httpcontext == null) throw new argumentnullexception("httpcontext"); // make sure user authenticated. if (!httpcontext.user.identity.isauthenticated) return false; // user's current roles var roles = system.web.security.roles.getrolesforuser(); hciroles currentroles = (hciroles)enum.parse(typeof(hciroles), string.join(",", roles)); // perform bitwise operation see if user's role // in passed in role values. if (roles != 0 && ((roles & currentroles) == 0)) return false; return true; } }
the problem system.web.security.roles.getrolesforuser() call isn't available in unit test , want mock way. can abstract call separate interface , use ninject inject web application can't find way same in unit test.
so if change attribute below
public class authorizewherein : authorizeattribute { [inject] iroleservice roleservice { get; set; } ... }
and unit test code along lines of:
[testmethod()] public void indextest() { var builder = new testcontrollerbuilder(); var controller = builder.createcontroller<usercontroller>(datalayer.object); var invoker = new actioninvoker<usercontroller>(); var mockmembershipservice = new mock<imembershipservice>(); mockmembershipservice.setup(x => x.getallusers(it.isany<int>(), it.isany<int>(), out total)).returns(new membershipusercollection()); controller.membershipservice = mockmembershipservice.object; builder.initializecontroller(controller); invoker.invokeaction(controller.controllercontext, x => x.index()); }
and controller being tested is:
[authorizewherein(roles = hciroles.admin)] public class usercontroller : basecontroller { public actionresult index() { return view(); } }
my question how can inject rolseservice depdency in unit test given can't directly access authroizewherein attribute?
i've read , re-read ninject filter extension mvc3 http://www.planetgeek.ch/2010/11/13/official-ninject-mvc-extension-gets-support-for-mvc3/ can't seem apply case.
given can't directly access authroizewherein attribute
why not accessing directly? that's trying test after all.
private class testcontroller : controller { } [testmethod] public void test() { // arrange var builder = new testcontrollerbuilder(); var controller = new testcontroller(); builder.initializecontroller(controller); controller.controllercontext = new controllercontext(builder.httpcontext, new routedata(), controller); var httpcontext = builder.httpcontext; httpcontext.stub(x => x.items).return(new hashtable()); var identity = new genericidentity("foo"); var roles = new string[0]; httpcontext.user = new genericprincipal(identity, roles); var ad = mockrepository.generatepartialmock<actiondescriptor>(); var context = new authorizationcontext(controller.controllercontext, ad); var sut = new authorizewherein(); var service = mockrepository.generayestub<iroleservice>(); sut.roleservice = service; // todo: set expectations on service // act sut.onauthorization(context); // assert // todo: assert on type of context.result // if httpunauthorizedresult authorization has failed // (i.e. custom authorizecore method returned false) }
Comments
Post a Comment