模拟框架无法处理泛型引用类型参数



我们一直在使用Simple.Moking作为单元测试的Mocking框架。最近,我对ICacheService进行了更改,它在我们的单元测试和模拟中被大量使用。

我所做的改变是添加了一种类似于以下的方法:

bool TrySetCache(string key,T data,ref T value);

此实现的语义无关紧要,因此请不要对引用类型参数的使用给出反馈。:)

一旦我们的CI构建开始并运行我们的自动化测试,由于模拟类型创建失败,它们都失败了。

我深入研究了这个项目,发现当它试图模拟泛型引用类型参数时,它失败了。

以下coee处理模拟方法参数的发射IL:

var baseMethodParameters = baseMethod.GetParameters();
        ilGenerator.Emit(OpCodes.Ldc_I4, baseMethodParameters.Length);
        ilGenerator.Emit(OpCodes.Newarr, typeof(object));
        ilGenerator.Emit(OpCodes.Stloc_2);
        for (int i = 0; i < baseMethodParameters.Length; i++)
        {
            var parameter = baseMethodParameters[i];
            var parameterType = parameter.ParameterType;
            ilGenerator.Emit(OpCodes.Ldloc_2);
            ilGenerator.Emit(OpCodes.Ldc_I4, i);
            ilGenerator.Emit(OpCodes.Ldarg, i + 1);
            if (parameterType.IsByRef)
            {
                parameterType = parameterType.GetRealTypeForByRefType();
                ilGenerator.EmitLoadIndirect(parameterType);
            }
            EmitBoxValue(ilGenerator, parameterType);
            ilGenerator.Emit(OpCodes.Stelem_Ref);
        }

更具体地说,处理引用类型参数的代码:

if (parameterType.IsByRef)
            {
                parameterType = parameterType.GetRealTypeForByRefType();
                ilGenerator.EmitLoadIndirect(parameterType);
            }

这调用了在使用通用引用类型参数时失败的扩展方法:

const string ByRefSpecifier = "&";
    public static Type GetRealTypeForByRefType(this Type type)
    {
        if (!type.IsByRef)
            throw new InvalidOperationException();
        return Type.GetType(type.AssemblyQualifiedName.Replace(ByRefSpecifier, string.Empty), true);
    }

return语句失败。

我想解决这个问题,但我不确定是否真的可以推断用法并模拟泛型引用类型参数。

如果事实上这是不可能的,那么我将添加一个检查,看看它是否是一个通用类型参数,如果是,则给出一条错误消息,这样用户就不需要花太长时间来解决问题。

重要提示调试时我注意到的一件事是,当它反映在我的ICacheService.TrySetCache(字符串键、T数据、ref T值)上时,它不会将最后一个参数标记为通用参数类型。

由于类型是泛型参数,AssemblyQualifiedName将为null。相反,几乎可以肯定的是,parameterType.GetRealTypeForByRefType()应该被parameterType.GetElementType()所取代。

相关内容

  • 没有找到相关文章

最新更新