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

使用Moq验证方法调用及返回结果(IsSuccessful为true)

统一验证泛型PerformAction的调用及返回结果

现有代码定义

class ClassA<T>
{
    T DoSomething();
}

class ResultWrapper<T>
{
    bool IsSuccessful;
    T Data;
}

class PerformAction<T>
{
    ResultWrapper<T> DoSomething()
    {
        try
        {
            var classA = new ClassA<T>();
            var result = new ResultWrapper<T>();
            result.Data = classA.DoSomething();
            result.IsSuccessful=true;
            return result;
        }
        catch(Exception)
        {
            var result = new ResultWrapper<T>();
            result.IsSuccessful=false;
            return result;
        }
    }
}

现有验证方式的局限

常规Moq验证只能检查PerformAction<T>的DoSomething方法是否被调用:

Mock<PerformAction<ABC>> mockObject = new Mock<PerformAction<ABC>>();
mockObject.Verify(x => x.DoSomething(), Times.Once());

但这种方式无法同时验证返回的ResultWrapper<T>.IsSuccessful是否为true。如果存在大量不同泛型参数的PerformAction实现(如PerformAction<BCD>、PerformAction<CDF>等),且mock在100处测试中被使用,每个测试都重复编写返回值断言会非常繁琐。

解决方案:创建通用验证扩展方法

通过扩展Moq的Mock类,实现一个通用的验证方法,一次性完成方法调用次数验证和返回结果断言:

扩展方法代码

using Moq;
using Xunit; // 替换为你使用的测试框架Assert类

public static class MockExtensions
{
    public static void VerifyDoSuccessfulAction<T>(this Mock<PerformAction<T>> mock, Times times)
    {
        // 验证方法调用次数
        mock.Verify(x => x.DoSomething(), times);
        
        // 获取返回值并验证IsSuccessful为true
        var result = mock.Object.DoSomething();
        Assert.True(result.IsSuccessful);
    }
}

使用方式

在任何测试中只需调用该扩展方法,无需重复编写断言:

Mock<PerformAction<ABC>> mock = new Mock<PerformAction<ABC>>();
// 预先模拟成功返回(如果需要)
mock.Setup(x => x.DoSomething()).Returns(new ResultWrapper<ABC> { IsSuccessful = true });

// 执行测试逻辑...

// 一次性完成两项验证
mock.VerifyDoSuccessfulAction(Times.Once());

进阶:自动生成成功mock

如果希望所有PerformAction<T>的mock默认返回成功结果,可以创建通用的mock创建方法,进一步减少重复代码:

public static Mock<PerformAction<T>> CreateSuccessfulPerformActionMock<T>()
{
    var mock = new Mock<PerformAction<T>>();
    mock.Setup(x => x.DoSomething()).Returns(new ResultWrapper<T> { IsSuccessful = true });
    return mock;
}

使用时直接创建mock即可:

var mock = CreateSuccessfulPerformActionMock<ABC>();
// 执行测试...
mock.VerifyDoSuccessfulAction(Times.Once());

替代方案:用Callback捕获返回值

如果不想编写扩展方法,也可以通过Callback捕获返回值后断言,但这种方式仍需每个测试重复编写:

ResultWrapper<ABC> result = null;
Mock<PerformAction<ABC>> mock = new Mock<PerformAction<ABC>>();
mock.Setup(x => x.DoSomething()).Returns(new ResultWrapper<ABC> { IsSuccessful = true })
    .Callback(() => result = mock.Object.DoSomething());

// 执行测试...

mock.Verify(x => x.DoSomething(), Times.Once());
Assert.True(result.IsSuccessful);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 00:42:58