开发者

How to mock up a static method in a static class with URLHelp? (Moq)

I have a extension method. Can any one help me how to test this method with Moq?

 public static string GetBaseUrl(this UrlHelper urlHelper)
    {
        Uri contextUri = new Uri(urlHelper.RequestContext.HttpContext.Requ开发者_StackOverflow社区est.Url, urlHelper.RequestContext.HttpContext.Request.RawUrl);
        UriBuilder realmUri = new UriBuilder(contextUri) { Path = urlHelper.RequestContext.HttpContext.Request.ApplicationPath, Query = null, Fragment = null };
        string url = realmUri.Uri.AbsoluteUri;

        if (url.EndsWith("/"))
        {
            url = url.Remove(url.Length - 1, 1); 
        }

        return url;
    }

many thanks.


As TrueWill points out, you can't use Moq directly with UrlHelper.RequestContext because it isn't virtual. On the other hand, UrlHelper is a public class that you can instantiate for use with unit testing.

At some point, however, you will encounter the need to assign a HttpContextBase to create the UrlHelper, and Moq can help you to do that.

Here's a test that shows that I can at least write a unit test that invokes your GetBaseUrl without throwing any exceptions:

[TestMethod]
public void Test1()
{
    var httpCtxStub = new Mock<HttpContextBase>();
    httpCtxStub.SetupGet(x => x.Request).Returns(() =>
        {
            var reqStub = new Mock<HttpRequestBase>();
            reqStub.SetupGet(r => r.RawUrl).Returns("http://foo");
            reqStub.SetupGet(r => r.Url).Returns(new Uri("http://foo"));
            return reqStub.Object;
        });

    var requestCtx = new RequestContext(httpCtxStub.Object, new RouteData());
    var urlHelper = new UrlHelper(requestCtx, new RouteCollection());

    var result = urlHelper.GetBaseUrl();

    // Assert something
}

However, this isn't the simplest unit test to write and maintain, so I support TrueWill's comment that you might make life simpler for yourself if you hide UrlHelper behind an interface.


The UrlHelper.RequestContext property is non-virtual. Moq isn't going to be of help in this case, to the best of my knowledge.

You could create a wrapper class for UrlHelper that implements an interface, but that would seem to defeat the purpose of using an extension method.

Typemock would probably do what you want, if you have the budget for a commercial program. (I haven't tried it; I use Moq myself.)

Another option would be to write integration tests against this method; while they would run more slowly than unit tests, I suspect this method is unlikely to version often.

A larger issue is coupling to UrlHelper reducing testability in the rest of your application. Perhaps other posters can suggest answers to that issue.

0

上一篇:

下一篇:

精彩评论

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

最新问答

问答排行榜