1

I was wondering how you could mock that a controller is decorated with the [Authorize] attribute in MVC3? I am using a custom membership provider. I would like to test that a controller been decorated with the attribute and you are authorized and what happens when you are not. I'm using Moq. Any good suggestions on this?!

UPDATE: I'm currently getting an NullreferenceException saying "object reference not set to an instance of an object". It's the same error as previously mentioned in this post NullReferenceException while using Authorize Attribute

This is related to the Authorize attribute. I'm running under iis and not using cassini. Does anyone know if this is somehow related to applicaton pool and user rights. The tests that I have for the authorize attribute wont work until this is fixed.

Maybe there is some other way of testing the Authorize attribute? Big thanks in advance.

UPDATE2 So after some extensive research and debugging help from a colleague I mentioned to fix the problem with the [Authorize] attribute. It appears as though this line in the web.config was missing:

<modules runAllManagedModulesForAllRequests="true">

Strangely enough this did not cause problem for another colleague that was sharing the trunk or in beta environment. It only caused problems for me locally. This might have been related to something in the GAC. Anyhow all works now.

Thanks.

Community
  • 1
  • 1
Tim
  • 531
  • 2
  • 7
  • 25
  • What do you execute in your test? A controller action? How do you execute it? Do you call it directly from your test suite as a normal method or is it called through the MVC infrastructure? – Tz_ Aug 23 '11 at 21:54
  • Good question. i have been on and off about this, not really sure how to go about. Yes a controller action. I'm through the MVC infrastructure is the "best" way to go about it. Or what do you think?! – Tim Aug 24 '11 at 04:46

1 Answers1

1

I wrote a blog post about exactly that a couple of months ago:

http://thomasardal.com/unit-testing-attribute-decorations/

ThomasArdal
  • 4,999
  • 4
  • 33
  • 73
  • That looks basically what I'm looking for. Although where hoping not to use another framework(Shoudly). Maybe I could use that extension method anyway. Thanks – Tim Aug 24 '11 at 08:05
  • You don't need to use Shouldly in order to use the extension method. The two are not linked in any way. All I'm writing is, that the method is inspired by Shoudly. You can copy the code to your own source code and use the method right away. – ThomasArdal Aug 24 '11 at 08:17
  • Right about that:). Will try it out and return with feedback. Thanks. – Tim Aug 24 '11 at 08:26
  • +1. It is a good pragmatic idea to just check the attribute declaration itself and rely on the framework that it will do what it is supposed to do with it. I was thinking about testing the behavior somehow (faking a whole HttpContext, ControllerContext and who-knows-what-else necessary), but it would be way too complicated without much additional benefit. I was also partly mislead by the question, as it mentioned mocking the attribute (meaning there is no attribute but you want to fake it for some purpose). – Tz_ Aug 24 '11 at 08:45
  • Yes the question might have been a bit misleading as Im not really sure how you should test this. As I thought that I trust the framework to take care of the redirects. I just wanted to test that a controller, or action is decorated with the Authorize attribute. – Tim Aug 24 '11 at 09:21
  • Thomas, I could not make it work properly. Cause here: var controller = new HomeController(); controller.ShouldHave(x => x.Index(), typeof(AuthorizeAttribute)); you use .ShouldHave and that I'm not sure how to apply to my case, any tips? – Tim Aug 25 '11 at 07:30
  • You need to create a new class in your test project. Name it something like AttributeExtensions. Make the class static and add the ShouldHave method from my blog-post. In your test you need to include the namespace where you've placed the AttributeExtensions class. That should do the trick :) – ThomasArdal Aug 25 '11 at 09:04
  • Worked as a charm, although Im getting an error saying that the Object reference is not set to an instance of an object?!! Have you experienced this? Thanks. – Tim Aug 25 '11 at 09:34
  • Nope sorry. Where do you get the error. In my code or your code? Maybe you could send a stacktrace. – ThomasArdal Aug 25 '11 at 11:23
  • Here is the stacktrace https://gist.github.com/1170471 though I think your code works fine. I think the Authorize attribute is not working. – Tim Aug 25 '11 at 11:34
  • @Thomas so now I realized that the AttributeExtensions class is throwing the error. More precisely here: var propertyInfo = memberExpression.Member as PropertyInfo; It's the same error as I mentioned before. – Tim Aug 26 '11 at 13:30
  • @Tim memberExpression is most likely null. Can you send the code from you test, where you use the ShouldHave method. Maybe I can help you to spot what goes wrong. Also did you add the Authorize attribute on a method? – ThomasArdal Aug 26 '11 at 17:44
  • @Thomas. Hmm I'm actually using it on the whole controller. The authorize attribute that is. My test is identical to yours. Then I guess rewrite the test so it reflects the fact that it is applied to a controller and not just a method? – Tim Aug 28 '11 at 21:01
  • The method is written to test that the Authorize attribute is present on a method and not the class. Can I see your test code where you use my method? I was wondering what you are writing in the lambda. – ThomasArdal Aug 29 '11 at 09:15
  • @Thomas: Sure, but as I said, Im using it as is, as you wrote it. https://gist.github.com/1178090 maybe I misses something in your tutorial. I thought that was enough?! Thanks! BTW I tries changing to just decorating the Index method with the attribute byt got the same error. – Tim Aug 29 '11 at 09:37
  • Hmm. Can't really see that you should have done anything wrong. I'm running out of options here :( I use the method in a lot of tests and it works great. Maybe it's a bit much, but if you create a simple project recreating the error, I will be happy to look at the error for you. – ThomasArdal Aug 29 '11 at 09:55
  • No. I know. Strange. I did as you said an started new fresh project and reproduced the error:MvcApplication4.AuthorizeAttributeSpec.should_validate_attribute: System.NullReferenceException : Object reference not set to an instance of an object. It is referring to this line: var propertyInfo = memberExpression.Member as PropertyInfo; Weird, I am merely decorating the Index method with the [Authorize] attribute, no role nothing else. – Tim Aug 29 '11 at 11:52
  • Yes thanks. Here is it https://gist.github.com/1178313 bare in mind the fact that I have two authorize attributes present is because I have been testing both things. – Tim Aug 29 '11 at 12:45
  • @ThomasArdal let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2953/discussion-between-tim-and-thomasardal) – Tim Aug 29 '11 at 12:45
  • Dough! The error was in my code. I've updated the blog post in order to avoid future confusion :) – ThomasArdal Aug 30 '11 at 06:22