如何配置Moq根据调用方方法返回不同布尔值?
问题描述
在单元测试场景中,某类的method()方法被FirstTrue()、SecondFalse()两个私有方法调用,需要配置该类的Moq对象,让method()被FirstTrue()调用时返回true,被SecondFalse()调用时返回false。尝试用反射获取当前方法名判断返回值的方案无效,求正确配置方式。
相关业务代码:
private bool FirstTrue() { return class.method(); }
private bool SecondFalse() { return class.method(); }
尝试的无效配置代码:
classMock.Setup(g => g.Method()) .Returns(() => { if (System.Reflection.MethodBase.GetCurrentMethod().Name == "FirstTrue") return true; else return false; });
正确配置方式
反射获取当前方法名无效的核心原因是:GetCurrentMethod()返回的是Moq生成的代理方法,而非实际调用method()的FirstTrue()或SecondFalse()。以下两种方案可实现需求:
方式一:按调用顺序配置(适用于调用顺序固定的场景)
如果FirstTrue()必然在SecondFalse()之前调用method(),可直接按调用顺序指定返回值:
classMock.Setup(g => g.Method()) .Returns(true) // 第一次调用返回true,对应FirstTrue()的调用 .Returns(false); // 第二次调用返回false,对应SecondFalse()的调用
方式二:分析调用栈获取调用方(适用于调用顺序不固定的场景)
通过StackTrace遍历调用栈,跳过Moq框架方法,定位到业务类中的私有调用方法:
using System.Diagnostics; classMock.Setup(g => g.Method()) .Returns(() => { var stackTrace = new StackTrace(); foreach (var frame in stackTrace.GetFrames()) { var method = frame.GetMethod(); // 替换YourBusinessClass为实际包含FirstTrue/SecondFalse的业务类类型 if (method.DeclaringType == typeof(YourBusinessClass) && method.IsPrivate) { return method.Name == "FirstTrue"; } } // 默认返回值,可根据需求调整 return false; });
注意事项
- 必须将
YourBusinessClass替换为实际业务类的类型。 - 调用栈分析存在一定性能开销,仅在调用顺序不固定时使用。
内容的提问来源于stack exchange,提问作者B.Quaink
相关产品推荐
相关产品推荐

