2

I am new in unit test and MVC development.
I have a question for using moq for unit testing in asp.net mvc. I have a controller which accepts an ajax action:

 [HttpPost,Authorize]
        public ActionResult GrabLink()
        {
            string username = HttpContext.User.Identity.Name;
            string rssUrl = Request.Params["Grablink"].ToString();
...}

This action deals with the http request which I generate from the view:

     var mockRequest = new Moq.Mock<HttpRequestBase>();

but I can not find a way to define the parameters I used in the class. Also, is there any way to use the value binding provider directly to pass the value to the controller if I would like to do an ajax post?

I am a newbie in handling web request. If you have some good tutorial for better understanding the Http request (as well as the Httpcontext and related classes in asp.net) please post here. Thank you very much!

3 Answers 3

2

This works very well for me:

var controller = new HomeController();

var context = new Mock<HttpContextBase>(MockBehavior.Strict);
var controllerContext = new Mock<ControllerContext>();

controllerContext.SetupGet(x => x.HttpContext.User.Identity.Name)
    .Returns("TestUser");
controllerContext.SetupGet(x => x.HttpContext.User.Identity.IsAuthenticated)
    .Returns(true);
controllerContext.SetupGet(x => x.HttpContext.Request.IsAuthenticated)
    .Returns(true);
controller.ControllerContext = controllerContext.Object;

// As a bonus, instantiate the Url helper to allow creating links
controller.Url = new UrlHelper(
    new RequestContext(context.Object, new RouteData()), new RouteCollection());

This will allow you to initialize any user you want as an authenticated user, and the last line will allow you to user the Url helper within the controller even though you're calling it from a unit test.

Sign up to request clarification or add additional context in comments.

1 Comment

This method looks really neat... I have learn a lot. Thank you!
1

As Scott said HttpContext makes Controllers hard to test. Anyway he's got a pretty solution at here.

BTW why didn't you make rssUrl a parameter if it is assigning by POST or GET?

e.g.

//POST: /GrabLink?rssUrl=bla bla...

[HttpPost,Authorize]
public ActionResult GrabLink(IPrincipal user, string rssUrl) {
    string userName = user.Name;
}

1 Comment

Thank you very much. Your solution looks really neat. I will try it later.
1

Ok, @cem covered your second question very well.

For your first, nerddinner, and If I'm not mistaken, when you create a new Internet Application with Unit test, in Visual Studio, have the following mock classes for HttpContext. Its at the bottom of this file.

You could use these (or create a new Internet App +Tests with VS) and copy all the fake classes for your tests. (I wrote a Moq example below)

It looks like this:

public class MockHttpContext : HttpContextBase {
    private IPrincipal _user;

    public override IPrincipal User {
        get {
            if (_user == null) {
                _user = new MockPrincipal();
            }
            return _user;
        }
        set {
            _user = value;
        }
    }

    public override HttpResponseBase Response
    {
        get
        {
            return new MockHttpResponse();
        }
    }
}

public class MockHttpResponse : HttpResponseBase {
    public override HttpCookieCollection Cookies
    {
        get
        {
            return new HttpCookieCollection();
        }
    }
}

Not tested, but to Use mock it would look like this:

var fakeReqBase = new Mock<HttpRequestBase>();
fakeReqBase.Setup(f => f.User).Returns(new GenericIdentity("FakeUser"));
//generic identity implements IIdentity
fakeUserRepo.Object;//this returns fake object of type HttpRequestBase

Checkout the Moq Quickstart. Its quite easy to get used to, and the fluent interface really helps.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.