如何在NSubstitute中用Lambda表达式模拟返回输入值的方法?
使用NSubstitute实现恒等行为的模拟场景
没问题,我来一步步帮你搞定这几个用NSubstitute模拟恒等逻辑的场景,都是单元测试里很常用的需求:
1. 模拟接收字符串返回自身的恒等函数
如果是要模拟一个接收单个字符串、返回该字符串本身的方法(比如委托或者接口方法),可以直接利用NSubstitute的Returns方法结合Lambda表达式,通过CallInfo获取传入的参数:
// 先假设我们有一个字符串处理的接口 public interface IStringProcessor { string Process(string input); } // 创建模拟对象并设置恒等行为 var processor = Substitute.For<IStringProcessor>(); processor.Process(Arg.Any<string>()).Returns(callInfo => callInfo.Arg<string>()); // 测试一下:输入"test"会返回"test" var result = processor.Process("test"); // result == "test"
如果是直接模拟Func<string, string>委托,写法更简洁:
var identityFunc = Substitute.For<Func<string, string>>(); identityFunc(Arg.Any<string>()).Returns(x => x.Arg<string>());
2. 模拟类Foo的Bar方法,返回输入的int值
这里要注意一个前提:类中的Bar方法必须是virtual或者抽象的,因为NSubstitute依赖动态代理来覆盖方法行为,非虚方法无法被模拟。
假设你的Foo类定义是这样:
public class Foo { // 必须是virtual才能被NSubstitute模拟 public virtual int Bar(int input) { // 原方法逻辑 return input * 2; } }
创建模拟对象并设置恒等行为的代码:
var fooMock = Substitute.For<Foo>(); // 对任意int输入,返回该输入值 fooMock.Bar(Arg.Any<int>()).Returns(callInfo => callInfo.Arg<int>()); // 测试:输入5返回5 var result = fooMock.Bar(5); // result == 5
如果Bar方法不是virtual,NSubstitute无法修改它的行为,这时候你可能需要把Bar方法抽象到接口里,或者修改类让方法变为虚方法。
3. 模拟接口IFoo的Func方法实现恒等行为
接口的方法天生就是可以被NSubstitute模拟的(因为接口成员默认是public abstract),所以这个场景非常直接:
假设你的接口定义是:
public interface IFoo { int Func(int x); }
创建模拟对象并设置恒等逻辑:
var ifooMock = Substitute.For<IFoo>(); // 对任意int参数x,返回x本身 ifooMock.Func(Arg.Any<int>()).Returns(callInfo => callInfo.Arg<int>()); // 验证:输入10返回10 var result = ifooMock.Func(10); // result == 10
关键知识点
这里Lambda表达式里的callInfo是NSubstitute的CallInfo对象,它包含了当前方法调用的所有参数信息。callInfo.Arg<T>()用来获取指定类型的参数,如果有多个参数,还可以用callInfo.ArgAt<T>(index)来按索引获取。
内容的提问来源于stack exchange,提问作者yuvalm2
相关产品推荐
相关产品推荐

