views:

532

answers:

3

I have a class that wraps the GetGlobalResourceObject and GetLocalResourceObjet so they can be used easily in MVC. The model validation classes then load the error messages dynamically from resource files. The problem is unit testing. The code uses "~/", and while everything functions correctly when the solution is run, I cannot see how to make the unit tests because I always receive the following error "System.Web.HttpException: The application relative virtual path '~/' cannot be made absolute, because the path to the application is not known."

The code that throws the exception is the following, used to evaluate an expression and return a global resource object.

Private Function GetExpressionFields(ByVal expression As String) As ResourceExpressionFields
    Return GetExpressionFields(expression, "~/")
End Function

Private Function GetExpressionFields(ByVal expression As String, ByVal path As String) As ResourceExpressionFields
    Dim context As New ExpressionBuilderContext(path)
    Dim resource_builder As New ResourceExpressionBuilder()
    Dim fields As ResourceExpressionFields
    fields = DirectCast(resource_builder.ParseExpression(expression, GetType(String), context), ResourceExpressionFields)
    Return fields
End Function

Any ideas on how to test this and other code that uses resource files?

+1  A: 

I took a slightly different approach. I use resource files outside of the App_* directories, in which case the IDE will add a custom tool to the file to generate a strongly typed wrapper for the resources that works anywhere in the solution, including in views, and behaves during unit tests: http://odetocode.com/Blogs/scott/archive/2009/07/15/13211.aspx

That's not an exact answer to your question, but I believe getting the App_* resources to behave correctly under all conditions was quite a bit of work.

OdeToCode
Thanks, it's not an exact answer to my problem, but it works great!
A: 

You could create a property in your ResourceExtensions class, for example bool IsInTestScope, and then in your test class set it on true, and inside method which returns localized text do something like this:

public static string Resource(this Controller controller, string expression, params object[] args)

{

if (!IsInTestScope)

{

ResourceExpressionFields fields = GetResourceFields(expression, "~/");

return GetGlobalResource(fields, args);

}

return string.Empty;

}

A: 

I've found approach for testing code that uses resources inside App_* directories. I described my solution in my blog link text

RredCat