We have recently upgraded to MvvMCross 6.2.2 and noticed we had to change to use Mvx.IoCProvider.
We have found that if we are constructing an MvxAsyncCommand in a ViewModel this causes a null reference exception on all unit tests that call this constructor
*
Result StackTrace:
at MvvmCross.Commands.MvxCommandBase..ctor()
at MvvmCross.Commands.MvxAsyncCommand..ctor(Func`1 execute, Func`1 canExecute, Boolean allowConcurrentExecutions)
at App.Mobile.Core.ViewModels.TestViewModel..ctor(IMvxNavigationService navigation, ITestService encService, ILogger logger)
at App.Mobile.Core.UnitTests.TestViewModelTests.<TestViewModel_Prepare>d__1.MoveNext()
*
Looking at the source in github the problem is due to Mvx.IocProvider being null.
public MvxCommandBase()
{
if (!Mvx.IoCProvider.TryResolve<IMvxCommandHelper>(out _commandHelper))
_commandHelper = new MvxWeakCommandHelper();
var alwaysOnUIThread = MvxSingletonCache.Instance == null || MvxSingletonCache.Instance.Settings.AlwaysRaiseInpcOnUserInterfaceThread;
ShouldAlwaysRaiseCECOnUserInterfaceThread = alwaysOnUIThread;
}
A fix has been implemented in the "develop" branch but this isn't available on nuget.
public MvxCommandBase()
{
// fallback on MvxWeakCommandHelper if no IoC has been set up
if (!Mvx.IoCProvider?.TryResolve(out _commandHelper) ?? true)
_commandHelper = new MvxWeakCommandHelper();
// default to true if no Singleton Cache has been set up
var alwaysOnUIThread = MvxSingletonCache.Instance?.Settings.AlwaysRaiseInpcOnUserInterfaceThread ?? true;
ShouldAlwaysRaiseCECOnUserInterfaceThread = alwaysOnUIThread;
}
Does anyone know of a workaround to initialize this IoCProvider within our unit test projects.
As you can see here the IoCProvider
is resolved by getting the singleton of IMvxIoCProvider
public static IMvxIoCProvider IoCProvider => MvxSingleton<IMvxIoCProvider>.Instance;
So all you have to do is to initialize the IMvxIoCProvider
.
As an example you can use this test, so in order to initialize it, you have to do:
MvxSingleton.ClearAllSingletons(); // This should be done in the test to clear all references of previous tests if necessary.
var instance = MvxIoCProvider.Initialize();
HIH