XUnit C# 如何使用Moq验证lambda表达式内的方法是否被调用
解决方案
核心思路是在Mock的PerformSafeOperation方法的回调中主动执行传入的lambda委托,让lambda内部的代码逻辑可以被执行,之后即可直接验证两个目标方法的调用情况。
前置假设
先明确IDatabaseAccess接口中PerformSafeOperation的常见签名(如果你的实际签名有差异可以对应调整):
public interface IDatabaseAccess { // 传入无返回值的委托作为参数 void PerformSafeOperation(Action operation); void SaveTask(Task task); void DoSomethingElse(SomeOtherObject someOtherObject); }
具体实现步骤
- 第一步:配置Mock的
PerformSafeOperation方法,收到调用时主动执行传入的委托 - 第二步:执行被测的
ApproveTask方法 - 第三步:验证
SaveTask和DoSomethingElse的调用次数、参数是否符合预期
完整测试代码示例
// 1. 初始化Mock对象和测试数据 var mockDatabaseAccess = new Mock<IDatabaseAccess>(); var testTask = new Task(); // 对应业务逻辑中传入的task实例 var testOtherObject = new SomeOtherObject(); // 对应业务逻辑中的someOtherObject实例 // 2. 关键配置:拦截PerformSafeOperation调用,执行传入的lambda mockDatabaseAccess .Setup(db => db.PerformSafeOperation(It.IsAny<Action>())) .Callback<Action>(operation => operation.Invoke()); // 3. 初始化被测系统,传入Mock依赖 var sut = new YourSutClass(mockDatabaseAccess.Object); // 4. 执行被测方法 sut.ApproveTask(testTask, testOtherObject); // 5. 验证两个目标方法是否按预期调用 mockDatabaseAccess.Verify(db => db.SaveTask(testTask), Times.Once); mockDatabaseAccess.Verify(db => db.DoSomethingElse(testOtherObject), Times.Once);
特殊场景适配
如果你的PerformSafeOperation是异步方法,签名如下:
Task PerformSafeOperation(Func<Task> operation);
对应调整Mock配置即可:
mockDatabaseAccess .Setup(db => db.PerformSafeOperation(It.IsAny<Func<Task>>())) .Returns<Func<Task>>(operation => operation.Invoke());
内容的提问来源于stack exchange,提问作者Kek
相关产品推荐
相关产品推荐

