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

MVVM Cross null references when unit testing MxvAsyncCommand

我们最近升级到 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()

*

查看 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;
    }

已在 "develop" 分支中实施修复,但这在 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;
    }

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

如您所见here IoCProvider 是通过获取 IMvxIoCProvider

的单例来解决的
public static IMvxIoCProvider IoCProvider => MvxSingleton<IMvxIoCProvider>.Instance;

所以你所要做的就是初始化IMvxIoCProvider。 作为一个例子,你可以使用 this test,所以为了初始化它,你必须这样做:

MvxSingleton.ClearAllSingletons(); // This should be done in the test to clear all references of previous tests if necessary.
var instance = MvxIoCProvider.Initialize();