单元测试 MxvAsyncCommand 时 MVVM 交叉空引用

1 mvvmcross

我们最近升级到 MvvMCross 6.2.2 并注意到我们必须更改为使用 Mvx.IoCProvider。

我们发现,如果我们在 ViewModel 中构造 MvxAsyncCommand,这会导致所有调用此构造函数的单元测试出现空引用异常

*

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()
Run Code Online (Sandbox Code Playgroud)

*

查看 github 中的源,问题是由于 Mvx.IocProvider 为空。

public MvxCommandBase()
    {
        if (!Mvx.IoCProvider.TryResolve<IMvxCommandHelper>(out _commandHelper))
            _commandHelper = new MvxWeakCommandHelper();

        var alwaysOnUIThread = MvxSingletonCache.Instance == null || MvxSingletonCache.Instance.Settings.AlwaysRaiseInpcOnUserInterfaceThread;
        ShouldAlwaysRaiseCECOnUserInterfaceThread = alwaysOnUIThread;
    }
Run Code Online (Sandbox Code Playgroud)

已在“开发”分支中实施了修复,但这在 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;
    }
Run Code Online (Sandbox Code Playgroud)

有谁知道在我们的单元测试项目中初始化这个 IoCProvider 的解决方法。

fma*_*oni 5

As you can see here the IoCProvider is resolved by getting the singleton of IMvxIoCProvider

public static IMvxIoCProvider IoCProvider => MvxSingleton<IMvxIoCProvider>.Instance;
Run Code Online (Sandbox Code Playgroud)

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();
Run Code Online (Sandbox Code Playgroud)

HIH