如何通过一次Moq Setup批量模拟类中同签名同返回值的所有方法?
批量模拟Moq中同签名方法的实现方式
你的场景是:需要模拟MyType中所有**无参且返回IReadOnlyList<Type>**的GetDeps相关方法,不想逐个手动写Setup,确实有更高效的实现方式,下面是两种可行方案:
方案一:反射+表达式树批量配置Setup
通过反射筛选出符合条件的方法,再用表达式树动态生成Moq的Setup逻辑,实现批量配置:
// 优先模拟接口IMyType(Moq对接口的支持更灵活) var mockMyType = new Mock<IMyType>(); // 筛选出所有符合条件的方法:无参、返回IReadOnlyList<Type> var targetMethods = typeof(IMyType).GetMethods(BindingFlags.Public | BindingFlags.Instance) .Where(m => m.GetParameters().Length == 0 && m.ReturnType == typeof(IReadOnlyList<Type>)); foreach (var method in targetMethods) { // 构建表达式树:x => x.目标方法() var paramExpr = Expression.Parameter(typeof(IMyType), "x"); var callExpr = Expression.Call(paramExpr, method); var lambdaExpr = Expression.Lambda<Func<IMyType, IReadOnlyList<Type>>>(callExpr, paramExpr); // 批量设置返回值 mockMyType.Setup(lambdaExpr) .Returns(new List<Type>().AsReadOnly()); }
如果必须模拟MyType类而非接口,需要确保这些方法是虚拟方法(virtual),否则Moq无法拦截并替换实现。
方案二:自定义默认值提供器
如果所有符合条件的方法都需要返回相同的默认值,可以通过Moq的DefaultValueProvider实现全局默认配置,无需逐个Setup:
// 自定义默认值提供器 public class DepsDefaultValueProvider : Moq.DefaultValueProvider { protected override object GetDefaultValue(Type type, Mock mock) { // 对返回IReadOnlyList<Type>的方法返回空只读列表 if (type == typeof(IReadOnlyList<Type>)) { return new List<Type>().AsReadOnly(); } // 其他类型沿用Moq默认逻辑 return base.GetDefaultValue(type, mock); } } // 使用方式 var mockMyType = new Mock<IMyType>(); mockMyType.DefaultValueProvider = new DepsDefaultValueProvider(); // 此时所有无参且返回IReadOnlyList<Type>的方法,调用时都会返回空只读列表
这个方案更简洁,尤其适合需要统一默认返回值的场景。
内容的提问来源于stack exchange,提问作者Parth Sekar
相关产品推荐
相关产品推荐

