Mock BaseViewModel时触发Microsoft.Maui未实现引用程序集异常
解决MAUI中Mock BaseViewModel时的NotImplementedInReferenceAssemblyException问题
这个错误的核心原因是你直接在BaseViewModel构造函数中调用了MAUI平台特定的静态Connectivity类,单元测试环境下的引用程序集未实现该类的具体逻辑,导致构造函数执行时抛出异常。要解决问题,必须通过依赖注入解耦平台API与ViewModel的依赖关系,具体步骤如下:
1. 定义网络连接服务接口
先封装网络连接操作,抽象出与平台无关的接口:
public interface IConnectivityService { bool IsInternetConnected { get; } event EventHandler<ConnectivityChangedEventArgs> ConnectivityChanged; }
2. 实现平台特定的连接服务
创建实现类,调用MAUI原生Connectivity:
public class MauiConnectivityService : IConnectivityService { public bool IsInternetConnected => Connectivity.NetworkAccess == NetworkAccess.Internet; public event EventHandler<ConnectivityChangedEventArgs> ConnectivityChanged { add => Connectivity.ConnectivityChanged += value; remove => Connectivity.ConnectivityChanged -= value; } }
3. 修改BaseViewModel,通过构造函数注入服务
不再直接依赖静态Connectivity,改用注入的接口:
public partial class BaseViewModel : ObservableObject { [ObservableProperty] private bool _internetConnected = true; private readonly IConnectivityService _connectivityService; public BaseViewModel(IConnectivityService connectivityService) { _connectivityService = connectivityService; InternetConnected = _connectivityService.IsInternetConnected; _connectivityService.ConnectivityChanged += ConnectivityHandler; } public void ConnectivityHandler(object sender, ConnectivityChangedEventArgs e) { InternetConnected = _connectivityService.IsInternetConnected; } // 销毁时取消订阅,避免内存泄漏 public virtual void Cleanup() { _connectivityService.ConnectivityChanged -= ConnectivityHandler; } }
4. 单元测试时Mock服务
用Moq等Mock框架模拟IConnectivityService,完全避开平台API调用:
[TestClass] public class YourViewModelTests { [TestMethod] public void TestViewModelInitialization() { // Mock连接服务 var mockConnectivity = new Mock<IConnectivityService>(); // 设置初始网络状态 mockConnectivity.Setup(s => s.IsInternetConnected).Returns(true); // 实例化子ViewModel var testViewModel = new YourTestViewModel(mockConnectivity.Object); // 验证初始状态 Assert.IsTrue(testViewModel.InternetConnected); } }
额外配置与注意事项
- 在MAUI项目的
MauiProgram.cs中注册服务:builder.Services.AddSingleton<IConnectivityService, MauiConnectivityService>(); - 子ViewModel构造函数需传递服务给基类:
public class YourTestViewModel : BaseViewModel { public YourTestViewModel(IConnectivityService connectivityService) : base(connectivityService) { // 子ViewModel逻辑 } }
这种方式彻底解耦了ViewModel与平台API的依赖,既解决了单元测试的Mock问题,也让代码更符合依赖倒置原则,易于维护和扩展。
内容的提问来源于stack exchange,提问作者Pratik Panchal
相关产品推荐
相关产品推荐

