如何解决混合使用来自同一类的已实现方法和模拟方法
现在,我确实发现了与stackoverflow here相关的内容。但是,没有建议的答案对我有帮助。
李的答案在大多数情况下可能是好的,但是在我的情况下这是不合适的,因为我真的需要模拟接口(具有各种实现)而不是类本身。
布兰登的答案非常接近,但我发现了以下建议。
这是为方便起见粘贴的他的代码:
var mock = new Mock<ITestClass>(); // Create Mock of interface
// Create instance of ITestClass implementation you want to use
var inst = new ActualTestClass();
// Setup to call method of an actual instance
// if method returns void use mock.Setup(...).Callback(...)
mock.Setup(m => m.someMethod(It.IsAny<int>())
.Returns((int x) => inst.someMethod(x));
引起我问题的是,该示例适用于简单的场景,但是如果“ SomeMethod()”调用它从具有模拟设置的ITestClass中调用另一个方法,则该示例将不起作用。在这种情况下,“ SomeMethod()”仍将使用实际实现。
为清楚起见:
说ITestClass实现方法SomeMethod和SomeOtherMethod。前者必须调用按以下方式嘲笑的后者:
mock.Setup(m => m.someOtherMethod(It.IsAny<bool>())
.Returns(true);
现在该模拟方法如何由SomeMethod代替真正的实现使用?
编辑
我需要模拟一个接口而不是类本身的另一个原因是,如果它是单例,则后一个选项将不允许您测试TestClass()。
解决方法
流行的隔离框架(例如Moq,NSubstitute或FakeItEasy)受到约束。不可能用它们解决您的问题。
还有不受约束的隔离框架:TypeMock,JustMock(均为付费)和MS Fakes(仅在VS Enterprise中可用)。
但是,我最近遇到了一个有趣的免费Pose库,它将解决您的问题。
添加package。
打开名称空间:
using Pose;
测试代码:
var inst = new ActualTestClass();
Shim testClassShim = Shim.Replace(() => inst.SomeOtherMethod(Is.A<bool>()))
.With((ActualTestClass _,bool b) => true);
int actual = 0;
PoseContext.Isolate(() =>
{
actual = inst.SomeMethod(1); // it will use shim inside
},testClassShim);
Assert.Equal(0,actual);
但是它在许多方面仍然不如商业同行。
应该注意的是,不受约束的工具虽然可以非常有效地解决隔离问题,但是以这种方式,它们可以避免设计错误,最终可能导致不良的应用程序体系结构。
,完全不用Moq怎么办?
您可以创建一个包装类,该包装类从您的主类派生,并使用所需的内容覆盖要模拟的方法。
然后在测试中使用此派生类。
当然,这些重写的方法可以使用Moq或从该派生类中定义为模拟。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。