user845405
user845405

Reputation: 1471

Mocking HttpContext.GetGlobalResourceObject() returns null

need your help in mocking HttpContext.GetGlobalResourceObject() so i can unit test my helper class . I could mock the HttpContextBase but for some reason when debugging the unit test the HttpContext.GetGlobalResourceObject() is always null ( noticed HttpContext.Current is null ). How do i fix this issue ?

Here is my static 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);
    }

}

Here are my unit tests

[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());
    }
}

Upvotes: 1

Views: 1298

Answers (1)

SBirthare
SBirthare

Reputation: 5137

The problem in your code above is, although you are setting up HttpContextBase its not connected with you code. So when the actual call made in your Translate method, the HttpContext is not what you mocked hence returning null always.

Since its a standalone class, setting up HttpContext is difficult. If this code is been invoked from a controller it would have been possible to write

controller.ControllerContext = myMockedContext; 

To fix this problem, you could work on the lines of solution provide by Mr. Joe in his answer, you could change your static helper class method something like this, injecting the HttpContextBase object:

    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);
    }

And from your test you could pass mocked contextBase object like so:

[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());
}

Upvotes: 1

Related Questions