单元测试求助:如何Mock接收Action<T>参数的方法?
如何Mock带Action参数的方法并测试逻辑?
你好呀!你的测试思路完全没问题,核心就是要Mock IInterface.MethodWithAction,然后手动触发传入的Action并传入测试用的字符串,这样就能验证MethodUnderTest里的逻辑是否正确。
解决方案:
在Callback里,我们需要接收传入的Action<string>参数,然后调用这个Action并传入测试方法的sampleString参数,这样就能触发MethodUnderTest里的Lambda表达式逻辑,计算出最终要返回的stringToBeTested。
完整的测试代码如下:
[TestMethod] [DataRow("Hello, World", "Hello,World")] [DataRow("Hello, World.", "")] [DataRow("Hello", "Hello")] public void MethodUnderTestReturnsCorrectString(string sampleString, string expected) { var mockObj = new Mock<IInterface>(); // 这里就是???处的代码:接收传入的Action<string>,并调用它传入sampleString mockObj.Setup(m => m.MethodWithAction(It.IsAny<Action<string>>())) .Callback<Action<string>>(action => action(sampleString)); ClassUnderTest sut = new ClassUnderTest(); sut.Obj = mockObj.Object; string actual = sut.MethodUnderTest(); Assert.Equal(expected, actual); }
为什么这么写?
Setup里用It.IsAny<Action<string>>()来匹配MethodWithAction接收的任意Action参数,确保我们的Mock能捕获到MethodUnderTest传入的Lambda。Callback<Action<string>>指定了回调的参数类型,拿到这个Action后,我们主动调用它并传入测试用的sampleString,这样就会执行MethodUnderTest里的str => { ... }逻辑,修改stringToBeTested的值。- 最后通过断言对比实际返回值和预期值,验证逻辑是否正确。
额外小提示:
如果你用的是较新版本的Moq,也可以用Setup的Callback重载,不用显式指定泛型参数,写法会更简洁:
mockObj.Setup(m => m.MethodWithAction(It.IsAny<Action<string>>())) .Callback((Action<string> action) => action(sampleString));
内容的提问来源于stack exchange,提问作者Anjesh Aggarwal
相关产品推荐
相关产品推荐

