You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过反射处理装饰器以验证内部mock是否被正确调用?

实现思路

核心逻辑

你可以结合反射+FakeItEasy的动态调用匹配能力实现批量验证,不需要为每个方法单独编写断言,步骤如下:

  • 第一步:初始化测试依赖,创建IFoo的Fake实例,再用该Fake实例构造FooDecorator对象。
  • 第二步:获取IFoo定义的所有公共实例方法,提前维护需要跳过验证的方法集合(比如存在特殊逻辑不需要委托的方法,可以直接存方法名,也可以通过自定义Attribute标记后反射筛选)。
  • 第三步:对每个需要验证的方法,通过反射调用FakeItEasy的A.Dummy()方法,生成对应参数类型的测试参数值。
  • 第四步:用反射调用装饰器实例的当前方法,传入上一步生成的参数集合。
  • 第五步:用FakeItEasy的动态调用匹配API,验证Fake实例的对应方法被调用了一次,且入参与传入装饰器的参数完全一致。

示例实现代码

using FakeItEasy;
using System.Reflection;

public void TestDecoratorDelegation()
{
    // 1. 初始化测试对象
    var fakeFoo = A.Fake<IFoo>();
    var decorator = new FooDecorator(fakeFoo);

    // 2. 配置跳过验证的方法列表,存方法名即可
    var skipMethods = new HashSet<string> { nameof(IFoo.需要跳过验证的方法名) };

    // 3. 遍历IFoo的所有公共实例方法
    var fooMethods = typeof(IFoo).GetMethods(BindingFlags.Public | BindingFlags.Instance);
    foreach (var method in fooMethods)
    {
        if (skipMethods.Contains(method.Name))
        {
            continue;
        }

        // 4. 生成对应参数的Dummy值
        var parameters = method.GetParameters();
        var args = new object[parameters.Length];
        for (int i = 0; i < parameters.Length; i++)
        {
            // 反射调用A.Dummy<T>生成对应类型的测试参数
            var dummyMethod = typeof(A).GetMethod(nameof(A.Dummy), BindingFlags.Public | BindingFlags.Static)
                .MakeGenericMethod(parameters[i].ParameterType);
            args[i] = dummyMethod.Invoke(null, null);
        }

        // 5. 调用装饰器的对应方法
        method.Invoke(decorator, args);

        // 6. 验证Fake的对应方法被正确调用,参数完全匹配
        A.CallTo(fakeFoo)
            .Where(call => call.Method == method)
            .WithArguments(args)
            .MustHaveHappenedOnceExactly();

        // 每次验证完重置Fake的调用记录,避免不同方法之间互相干扰
        Fake.ClearRecordedCalls(fakeFoo);
    }
}

扩展优化

如果需要更灵活的跳过规则,可以自定义一个[SkipDelegationVerification]特性,打在装饰器有特殊逻辑的方法上,反射遍历的时候判断方法是否带有该特性即可自动跳过,不需要手动维护方法名列表。

内容的提问来源于stack exchange,提问作者Mike

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 02:45:01