Skip to content

How to make JSON Localization work in Unit Test project

imgen edited this page Apr 27, 2014 · 2 revisions

To make the JSON localization work, here is what I do now:

    1. Have xxx.json file marked as Resource file in Visual Studio's File Properties tab. The same as the Babel example in MvvmCross tutorials which can be found here
    1. Add the plugin needed. Json, JsonLocalization, ResourceLoader, etc using Nuget which will add plugin XxxBootstrap classes
    1. Use the below code to initialize in the Setup of the unit test
            IMvxPluginManager pluginManager = new MvxFilePluginManager(".wpf", string.Empty);
            Ioc.RegisterSingleton(pluginManager);
            new ResourceLoaderPluginBootstrap().Run();
            new JsonPluginBootstrap().Run();
            new JsonLocalisationPluginBootstrap().Run();

            var builder = new TextProviderBuilder();
            Mvx.RegisterSingleton<IMvxTextProviderBuilder>(builder);
            Mvx.RegisterSingleton(builder.TextProvider);
    1. add WPF assemblies, like WindowBase.dll, System.Windows.dll, System.Xaml.dll, PresentationFramework.dll. This is for WPF ResourceLoader plugin to work.
    1. we have to ensure that System.Reflection.Assembly.GetEntryAssembly not return null for below code in WPF ResourceLoader plugin
    public class MvxWpfResourceLoader : MvxResourceLoader
    {
        public override void GetResourceStream(string resourcePath, Action<Stream> streamAction)
        {
            StreamResourceInfo resourceStream = Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative));
            if (resourceStream != null)
            {
                streamAction(resourceStream.Stream);
            }
            else
            {
                streamAction(null);
            }
        }
    }

The cirtical line is Application.GetResourceStream(new Uri(resourcePath, UriKind.Relative)) which will call Assembly.GetEntryAssembly() method.

For this I change the test assembly's output type to Console and Run the unit test in the App.Main method like below

    class App
    {
        public static void Main(string[] args)
        {
            var testHomeViewModel = new TestHomeViewModel();
            testHomeViewModel.SetUp();
            testHomeViewModel.TestShareCommand();
        }
    }

Alternatively, arguably better approach would be to use the below code to set the Entry Assembly

        public static void SetEntryAssembly()
        {
            SetEntryAssembly(Assembly.GetExecutingAssembly());
        }

        /// <summary>
        /// Allows setting the Entry Assembly when needed. 
        /// Use AssemblyUtilities.SetEntryAssembly() as first line in XNA ad hoc tests
        /// </summary>
        /// <param name="assembly">Assembly to set as entry assembly</param>
        public static void SetEntryAssembly(Assembly assembly)
        {
            AppDomainManager manager = new AppDomainManager();
            FieldInfo entryAssemblyfield = manager.GetType().GetField("m_entryAssembly", BindingFlags.Instance | BindingFlags.NonPublic);
            entryAssemblyfield.SetValue(manager, assembly);

            AppDomain domain = AppDomain.CurrentDomain;
            FieldInfo domainManagerField = domain.GetType().GetField("_domainManager", BindingFlags.Instance | BindingFlags.NonPublic);
            domainManagerField.SetValue(domain, manager);
        }

I found this clever trick from this answer on Stackoverflow That should do the trick, :)