开发者

Unit Testing Custom Model Binder - Fake HttpContext Issue

I have the following unit test defined to test my model binder:

[TestMethod]
public void DateTime_Works() {
    // Arrange
    var controllerContext = FakeContext.GetAuthenticatedControllerContext(new Mock<Controller>().Object, "TestAdmin");

    var values = new NameValueCollection {
        { "Foo.Date", "12/02/1964" },
        { "Foo.Hour", "12" },
        { "Foo.Minute", "00" },
        { "Foo.Second", "00" }
    };

    var bindingContext = new ModelBindingContext() { ModelName = "Foo", ValueProvider = new NameValueCollectionValueProvider(values, null) };
    var binder = new DateAndTimeModelBinder();

    // Act
    var result = (DateTime)binder.BindModel(controllerContext, bindingContext);

    // Assert
    Assert.AreEqual(DateTime.Parse("1964-12-02 12:00:00"), result);
}

Here is the FakeContext class:

public static class FakeContext {
    public static HttpContextBase GetHttpContext(string usern开发者_开发问答ame) {
        var context = new Mock<HttpContextBase>();
        context.SetupGet(ctx => ctx.Request.IsAuthenticated).Returns(!string.IsNullOrEmpty(username));

        return context.Object;
    }

    public static ControllerContext GetControllerContext(Controller controller) {
        return GetAuthenticatedControllerContext(controller, null);
    }

    public static ControllerContext GetAuthenticatedControllerContext(Controller controller, string username) {
        var httpContext = GetHttpContext(username);
        return new ControllerContext(httpContext, new RouteData(), controller);
    }
}

Within my model binder i call a utility method which has the following line in it:

HttpContext.Current.User.Identity.IsAuthenticated

This seems to always return false even when I pass a username in. I was wondering how the GetHttpContext method can be modified to mock this out aswell.

I'd appreciate the help. Thanks


You are mocking the IsAuthenticated property of the Request and not of the User Identity. Your mock is indicating that the request has been authenticated, but has nothing to do with the identity authentication.

Changing your mock up a little should fix your problem.

var identityMock = new Mock<IIdentity>();
identityMock.SetupGet( i => i.IsAuthenticated ).Returns( !string.IsNullOrEmpty(username));

var userMock = new Mock<IPrincipal>();
userMock.SetupGet( u => u.Identity ). Returns( identityMock.Object );

var context = new Mock<HttpContextBase>();
context.SetupGet( ctx => ctx.User ).Returns( userMock.Object );

Edit The more I thought about it the more I felt these mocks needed to be setup seperatly

Note, I have not executed this code. It should get you what you need however.

MSDN for Request.IsAuthenticated http://msdn.microsoft.com/en-us/library/system.web.httprequest.isauthenticated.aspx

MSDN for User.Identity.IsAuthenticated http://msdn.microsoft.com/en-us/library/system.security.principal.iidentity.isauthenticated.aspx

Hope this helps.


You could use Moq and follow the advice found here:

Moq: unit testing a method relying on HttpContext

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜