Isabella
---- I fell upon the thorn of life, I bleed.
Some time ago I start to play with ASP.NET MVC. It is very well pattern and Microsoft made nice choose that implemented it for ASP.NET in my opinion.
I started a project that uses ASP.NET MVC. This project requests multilingual support. I use resources for this. It works well when I use resource's properties in the View's layer but when I call resource's properties from code behind. It's something likes to next:
public ActionResult Index()
{
ViewData["Message"] = CommonResource.WELCOME;
return View();
}
It works but I pay attention that this code breaks my Unit Tests. My Unit Tests looks like:
[TestMethod]
public void Index_Test()
{
//// Arrange
var controller = new HomeController();
// Act
var result = controller.Index();
// Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
}
It happens because I run my code in other project and my ResourceManager is not filled (it equals to null). How can I fix it? A first idea that came to mind is "extract interface".. but it is very annoying because resource's class is auto-generate and I should update this code after each updating of resources.. I made some research and found additional way for extracting resources - HttpContext contains GetGlobalResourceObject method! It is well way because I can set mock for HttpContext and for any its methods or properties.
Note: GetGlobalResourceObject returns object but I use only strings for localization. So I create linq method for HttpContext that returns string if it presents:
public static string GetGlobalResource(
   this HttpContextBase httpContext
  , string classKey, string resourceKey)
{
var result = httpContext.GetGlobalResourceObject
                    (classKey, resourceKey);
return null != result
  ? result.ToString() : string.Empty;
}
Pay attention, MissingManifestResourceException is possible in this code if you pass incorrect key/keys!
So I change pieces of code in Controller's classes in the next manner:
public ActionResult Index()
{
ViewData[CommonStrings.MESSAGE] = HttpContext
        .GetGlobalResource(CommonStrings
            .COMMON_RESOURCE, CommonStrings.WELCOME);
return View();
}
After it I should change my Unit Test's methods in next manner:
[TestMethod]
public void Index_Test()
{
//// Arrange
var httpContextMock = MockRepository
              .GenerateMock<HttpContextBase>();
httpContextMock.Stub
   (x => x.GetGlobalResource(
      CommonStrings.COMMON_RESOURCE, CommonStrings.WELCOME))
   .Return(CommonStrings.WELCOME);
var controller = new HomeController();
var context = new ControllerContext
  (httpContextMock, new RouteData(), controller);
controller.ControllerContext = context;
// Act
var result = controller.Index();
// Assert
Assert.IsInstanceOfType(result, typeof(ViewResult));
ViewDataDictionary viewData = ((ViewResult)result).ViewData;
Assert.AreEqual(CommonStrings.WELCOME
        , viewData[CommonStrings.MESSAGE]);
}
Moreover, you can see that I added additional checking related to localization.
posted on 2012-08-14 17:17  李昀璟  阅读(522)  评论(0编辑  收藏  举报