I'd like to write (in c#) a unit-test for an MVC controller action which might return one view or the other, depending on whether the request is authenticated. How can this be done?
Asked
Active
Viewed 1.1k times
2 Answers
37
You can mock your Request. Something like this (Moq using):
var request = new Mock<HttpRequestBase>();
request.SetupGet(x => x.IsAuthenticated).Returns(true); // or false
var context = new Mock<HttpContextBase>();
context.SetupGet(x => x.Request).Returns(request.Object);
var controller = new YourController();
controller.ControllerContext =
new ControllerContext(context.Object, new RouteData(), controller);
// test
ViewResult viewResult = (ViewResult)controller.SomeAction();
Assert.True(viewResult.ViewName == "ViewForAuthenticatedRequest");
-
This doesn't work for me - returns the same viewname regardless of true/false – Kev Dec 13 '16 at 12:41
17
Using mocking and dependency injection. The following assumes that you're checking that it is authenticated and then accessing the user object to get the user's id. Uses RhinoMocks.
// mock context variables
var username = "user";
var httpContext = MockRepository.GenerateMock<HttpContextBase>();
var request = MockRepository.GenerateMock<HttpRequestBase>();
var identity = MockRepository.GenerateMock<IIdentity>();
var principal = MockRepository.GenerateMock<IPrincipal>();
httpContext.Expect( c => c.Request ).Return( request ).Repeat.AtLeastOnce();
request.Expect( r => r.IsAuthenticated ).Return( true ).Repeat.AtLeastOnce();
httpContext.Expect( c => c.User ).Return( principal ).Repeat.AtLeastOnce();
principal.Expect( p => p.Identity ).Return( identity ).Repeat.AtLeastOnce();
identity.Expect( i => i.Name ).Return( username ).Repeat.AtLeastOnce();
var controller = new MyController();
// inject context
controller.ControllerContext = new ControllerContext( httpContext,
new RouteData(),
controller );
var result = controller.MyAction() as ViewResult;
Assert.IsNotNull( result );
// verify that expectations were met
identity.VerifyAllExpectations();
principal.VerifyAllExpectations();
request.VerifyAllExpectations();
httpContext.VerifyAllExpectations();
SteveC
- 15,808
- 23
- 102
- 173
tvanfosson
- 524,688
- 99
- 697
- 795
-
1thanks for your answer which i'm sure is working excellently. since I've tested eu-ge-ne answer (which works fine for me) and he was a little faster with the response, I marked his answer. no offense. have a good day. ;) – Mats Jul 10 '09 at 06:40
-
1Not a problem. It's really the same answer. I only left mine because it shows how to mock the principal/identity in case you need to get at the username -- or the IsInRole method on the principal, which I haven't shown. – tvanfosson Jul 10 '09 at 10:47