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

如何捕获C#中Mock对象方法的返回值并验证?

问题描述

我有如下C#方法:

public class MyClass {

   public bool foo(Dependency dependency)
   {
       bool result = false;
            
       var metadata = dependency.dependencyMethod();
            
       if(metadata.containsProperty()){
           // doSomething
       } else
       {
           // doSomethingElse
       }

       return result;
   }
}

我希望捕获dependency.dependencyMethod()的返回值(即方法中metadata变量的值),并断言该返回值与我为Mock对象定义的预设响应值一致。我的测试代码如下:

//Arrange
MyClass myClass = new MyClass(); // System Under Test
Mock<Dependency> dependencyMock = new Mock<Dependency>(); //Mocking dependency

// Mocking the behavior of the dependencyMock to return a pre-defined value when invoked
dependencyMock
    .Setup(d => d.dependencyMethod())
    .Returns("dummyMetadata");

// How do we capture the value returned when `dependencyMock.dependencyMethod()` gets invoked?
dependencyMock
    .Setup(d => d.dependencyMethod()) // When invoking the `dependencyMethod()`
    .Callback(); // <--- How to Capture the value returned when d.dependencyMethod() gets called, and assert that it matches "dummyMetaData"?

// Act
myClass.foo(dependencyMock);

我能否捕获dependencyMock.dependencyMethod()的返回值?即使该返回值是Mock的,我也希望捕获它并确认预设的Mock响应确实被返回。

解决方案

首先明确:你其实不需要刻意捕获Mock方法的返回值来断言它和预设值一致——因为你已经通过Returns("dummyMetadata")强制Mock返回这个值了,只要方法被正确调用,返回值必然是你预设的内容。

不过如果你一定要验证这个逻辑,或者想确认被测试类(SUT)确实拿到了这个返回值,可以用以下几种方式:

方式1:验证Mock方法的调用次数(最直接)

既然已经预设了返回值,只要验证dependencyMethod被调用过,就说明foo方法确实拿到了你预设的返回值。在Act步骤后添加断言:

// Assert
dependencyMock.Verify(d => d.dependencyMethod(), Times.Once);

这能确保foo方法正确调用了依赖的dependencyMethod,结合之前的Setup配置,就等同于确认SUT拿到了预设的dummyMetadata。

方式2:用Callback捕获返回值(如果一定要拿到具体值)

如果你确实需要捕获返回值,可以在Setup时把预设值存到变量里,再通过Callback赋值并断言:

// Arrange
string expectedMetadata = "dummyMetadata";
MyClass myClass = new MyClass();
Mock<Dependency> dependencyMock = new Mock<Dependency>();

string capturedMetadata = null;
dependencyMock
    .Setup(d => d.dependencyMethod())
    .Returns(expectedMetadata)
    .Callback(() => {
        capturedMetadata = expectedMetadata;
    });

// Act
myClass.foo(dependencyMock.Object); // 注意:必须传mock的Object属性,而非Mock容器本身!

// Assert
Assert.AreEqual(expectedMetadata, capturedMetadata);

重要修正:你的测试代码里存在一个错误——调用myClass.foo(dependencyMock)是不正确的,应该传递dependencyMock.Object,因为Mock<T>是Mock的管理容器,真正的依赖实例是它的Object属性。

方式3:验证预设逻辑的有效性

如果你担心预设的返回值没生效,其实完全没必要——Moq的Setup是强绑定的,只要方法调用的匹配条件符合,就一定会返回你设置的值。验证调用次数已经足够确认逻辑的正确性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 06:40:43