Mocking HttpContext.GetGlobalResourceObject()返回null

时间:2014-11-11 05:17:07

标签: c# asp.net-mvc asp.net-mvc-4 unit-testing moq

在模拟HttpContext.GetGlobalResourceObject()时需要你的帮助,所以我可以对我的助手类进行单元测试。我可以模拟HttpContextBase,但出于某种原因调试单元测试时 HttpContext.GetGlobalResourceObject()始终为null(注意HttpContext.Current为空)。我该如何解决这个问题?

这是我的静态HelperClass

public static class HtmlHelperExtentions
{
    public static string GetBrandedCssBundle(this HtmlHelper htmlHelper)
    {
        return "BrandTest";
    }

    public static HtmlString Translate(this HtmlHelper htmlhelper, string defaultString, string key, params object[] objects)
    {
        var resource = HttpContext.GetGlobalResourceObject(null, key);

        if (resource != null)
        {
            defaultString = resource.ToString();
        }

        return objects.Length > 0 ? new HtmlString(string.Format(defaultString, objects)) : new HtmlString(defaultString);
    }

}

以下是我的单元测试

[TestClass]
public class HtmlHelperTest
{

    Mock<HttpContextBase> contextBase {get;private set;};

    [TestInitialize()]
    public void Initializer()
    {
        var context = new Mock<HttpContextBase>();
        var request = new Mock<HttpRequestBase>();
        var response = new Mock<HttpResponseBase>();
        var session = new Mock<HttpSessionStateBase>();
        var server = new Mock<HttpServerUtilityBase>();
        var user = new Mock<IPrincipal>();
        var identity = new Mock<IIdentity>();

        context.Setup(ctx => ctx.Request).Returns(request.Object);
        context.Setup(ctx => ctx.Response).Returns(response.Object);
        context.Setup(ctx => ctx.Session).Returns(session.Object);
        context.Setup(ctx => ctx.Server).Returns(server.Object);
        context.Setup(ctx => ctx.User).Returns(user.Object);
        user.Setup(ctx => ctx.Identity).Returns(identity.Object);
        identity.Setup(id => id.IsAuthenticated).Returns(true);
        identity.Setup(id => id.Name).Returns("test");
        context.Setup(ctx => ctx.Response.Cache).Returns(CreateCachePolicy());

        contextBase = context;

    }

    [TestCleanup]
    public void TestCleanup()
    {
        HttpContext.Current = null;
    }


    [TestMethod]
    [TestCategory(TestCategoryType.UnitTest)]
    public void HtmlHelperExtentions_Translate_WithValidInputs_ReturnsTranslatedContent()
    {
        // Arrange          
        var defaultstring = "TestMessage";
        var inputkey = "XX.Areas.Onboarding.{0}Messages.Message_Onboarding_XX_1001";
        var expectedvalue = "HolaMessage";
        HtmlHelper htmlhelper = null;
        contextBase.Setup(ctx => ctx.GetGlobalResourceObject(null, 
        inputkey)).Returns(expectedvalue);

        //Act
        var result = HtmlHelperExtentions.Translate(htmlhelper, null, inputkey);

        //Assert            
        Assert.IsNotNull(result);
        Assert.AreEqual(expectedvalue, result.ToString());
    }
}

1 个答案:

答案 0 :(得分:0)

上面代码中的问题是,虽然您设置的HttpContextBase与您的代码无关。因此,当您使用Translate方法进行实际调用时,HttpContext不是您嘲笑的,因此始终返回null。

由于它是一个独立的类,因此设置HttpContext很困难。如果从控制器调用此代码,则可以编写

controller.ControllerContext = myMockedContext; 

要解决这个问题,你可以使用Joe先生在answer中提供的解决方案,你可以改变你的静态帮助类方法,注入HttpContextBase对象:

    public static HtmlString Translate(this HtmlHelper htmlhelper, HttpContextBase contextBase, string defaultString, string key, params object[] objects)
    {
        var resource = contextBase.GetGlobalResourceObject(null, key);

        if (resource != null)
        {
            defaultString = resource.ToString();
        }

        return objects.Length > 0 ? new HtmlString(string.Format(defaultString, objects)) : new HtmlString(defaultString);
    }

从测试中你可以像这样传递模拟的contextBase对象:

[TestMethod]
public void HtmlHelperExtentions_Translate_WithValidInputs_ReturnsTranslatedContent()
{
    // Arrange          
    var defaultstring = "TestMessage";
    var inputkey = "XX.Areas.Onboarding.{0}Messages.Message_Onboarding_XX_1001";
    var expectedvalue = "HolaMessage";
    HtmlHelper htmlhelper = null;
    contextBase.Setup(ctx => ctx.GetGlobalResourceObject(null, inputkey)).Returns(expectedvalue);

    //Act
    var result = HtmlHelperExtentions.Translate(htmlhelper, contextBase.Object, defaultstring, inputkey);

    //Assert            
    Assert.IsNotNull(result);
    Assert.AreEqual(expectedvalue, result.ToString());
}