.netasp.net-mvc-3unit-testingmoqapp-globalresources

How do you Moq a .resx that lives in App_GlobalResource?


I'm writing unit tests for a controller in an MVC3 web project, but my tests throw exceptions when they try and access a resource like this:

return Index(Resources.Strings.MyStringResource);

The resource is a .resx file titled Strings.

I'm using the Moq libraries to achieve unit test for HttpContextBase functionality, so I was wondering how I would go about using the Moq libraries to access an App_GlobalResource.

Any help or pointers would be greatly appreciated!


Solution

  • You can't, at least not directly. The strongly-typed classes that are generated from resource (.resx) files expose static, not instance methods.

    Because of this, they can't implement an interface method, nor are they virtual; Moq requires that at least one of these conditions are met in order to create a mock.

    To get around this, you would create an abstraction, like anything else:

    public interface IResources
    {
        string MyStringResource { get; }
    }
    

    You'd pass (or inject) an implementation of this into your controller, and then pass that to your Index method. That implementation might look something like this:

    public class ResourcesWrapper : IResources
    {
        public string MyStringResource 
        { 
            get 
            { 
                return Resources.Strings.MyStringResource; 
            } 
        }
    }
    

    Then, when you're testing, you can use Moq to create a mock of the IResources interface, and pass that to your controller, like so:

    // Create the mock.
    var mock = new Mock<IResources>();
    
    // Setup the property.
    mock.SetupProperty(m => m.MyStringResource, "My Mocked Value");
    
    // Pass the object somewhere for use.
    Assert.AreEqual(mock.Object.MyStringResource, "My Mocked Value");