Xamarin中NUnit+Moq单元测试:ILogManager.GetLog返回null问题求助
解决Xamarin测试中ILogManager.GetLog()返回null的问题
我来帮你定位问题并给出修复方案:
问题根源
你的测试代码里有两个关键错误导致GetLog()返回null:
- 未配置
ILogManager.GetLog()的返回值:你创建了_logManager这个Mock实例,但没有指定它的GetLog方法应该返回什么。在Moq中,未设置的方法默认返回null(如果用了Strict模式,甚至会直接抛出异常)。 DependencyService.Get<ILoggingService>()配置逻辑错误:你在Setup阶段直接调用_logManager.Object.GetLog()作为返回值,但此时GetLog还未被配置,这行代码会提前返回null,导致后续获取ILoggingService也得到null。
修复后的Setup代码
[SetUpFixture] public class Setup { public static readonly Mock<IDependencyService> MockedService = new Mock<IDependencyService>(MockBehavior.Strict); readonly Mock<ILogManager> _logManager = new Mock<ILogManager>(MockBehavior.Strict); readonly Mock<ILoggingService> _loggingService = new Mock<ILoggingService>(MockBehavior.Strict); [OneTimeSetUp] public void OneTimeSetUp() { // 第一步:配置LogManager的GetLog方法,返回预先Mock好的LoggingService // 用It.IsAny<string>()匹配任意callerFilePath参数(适配默认的调用方文件路径参数) _logManager.Setup(m => m.GetLog(It.IsAny<string>())) .Returns(_loggingService.Object); // 第二步:配置DependencyService返回LogManager的Mock实例 MockedService.Setup(p => p.Get<ILogManager>()).Returns(_logManager.Object); // 第三步:如果应用需要直接从DependencyService获取ILoggingService // 直接返回LoggingService的Mock实例,避免通过未初始化的LogManager获取 MockedService.Setup(p => p.Get<ILoggingService>()).Returns(_loggingService.Object); } [OneTimeTearDown] public void OneTimeTearDown() { } }
额外注意事项
- Strict模式的要求:因为你使用了
MockBehavior.Strict,所有会被测试代码调用的方法都必须提前配置。比如业务代码如果调用ILoggingService.Info(),你需要在Setup中添加空实现配置:// 在OneTimeSetUp中添加,避免每个测试重复配置 _loggingService.Setup(l => l.Info(It.IsAny<string>())); _loggingService.Setup(l => l.Info(It.IsAny<string>(), It.IsAny<object[]>())); // 同理给Error、Debug、Warn等方法添加对应配置 - 验证日志调用:如果需要验证业务代码是否正确触发了日志,可以在测试方法中通过
_loggingService实例验证:// 示例:验证Info方法被调用了一次,参数为"Test log message" Setup._loggingService.Verify(l => l.Info("Test log message"), Times.Once);
内容的提问来源于stack exchange,提问作者StezPet
相关产品推荐
相关产品推荐

