如何创建和使用部分存根(以最小起订量)而不依赖于具体实现?
我有使用 MoQ 创建部分存根的代码。我更喜欢与接口而不是具体实现进行交互,这样如果我有不同的接口实现,我就不必修改单元测试。
例如,我有一个工厂方法,例如:
private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
return new Mock<SomeConcreteImplementation>();
}
这是调用该方法的代码:
var partialStub = ISomeInterfaceStubFactory();
partialStub.Setup(m => m.MethodToStubOutThatMethodToTestCalls(It.IsAny<string>())).Returns(new List<SomeOtherObject>());
partialStub.CallBase = true;
var actualResult= partialStub.Object.MethodToTest();
Assert.That(actualResult, Is.EqualTo(expectedResult));
问题是,执行此操作时 ISomeInterfaceStubFactory 将无法编译。所以我将其更改为如下所示,但这样做似乎破坏了部分存根。实际实现的 MethodToStubOutThatMethodToTestCalls
操作被调用,而不是存根版本。基本上我试图将多态性与存根对象一起使用。有办法做到这一点吗?我希望我的单元测试不要与具体实现高度耦合。
private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
return new Mock<SomeConcreteImplementation>.As<ISomeInterface>();
}
I have code that uses MoQ to create a partial stub. I'd prefer to interact with the interface instead of the concrete implementation so that I won't have to modify the unit test if I have a different implementation of the interface.
So for example, I have a factory method such as:
private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
return new Mock<SomeConcreteImplementation>();
}
Here is the code that calls the method:
var partialStub = ISomeInterfaceStubFactory();
partialStub.Setup(m => m.MethodToStubOutThatMethodToTestCalls(It.IsAny<string>())).Returns(new List<SomeOtherObject>());
partialStub.CallBase = true;
var actualResult= partialStub.Object.MethodToTest();
Assert.That(actualResult, Is.EqualTo(expectedResult));
The problem is that when doing this is that ISomeInterfaceStubFactory won't compile. So I changed it to be like below, but doing this seems to break the partial stub. The actual implemented MethodToStubOutThatMethodToTestCalls
operation gets called, not the stubbed version. Basically I'm trying to use polymorphism with the stub object. Is there anyway to do this? I'd like my unit test to not be highly coupled to the concrete implementation.
private Mock<ISomeInterface> ISomeInterfaceStubFactory()
{
return new Mock<SomeConcreteImplementation>.As<ISomeInterface>();
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我认为您错过了模拟对象的要点。从具体实现返回模拟是没有意义的。这个想法是让被测试的类依赖于一些你可以模拟的接口或抽象。
I think you are missing the point of mock objects. Returning a mock from a concrete implementation makes no sense. The idea is to have the class under test depend on some interface or abstract which you could mock.
根据您的澄清修改我的答案。我并不反对arootbeer,但我确实想了解你在做什么以及为什么它不起作用。
这是我认为您正在尝试做的一个简单示例。对于这两种具体实现,我的测试都通过了。这就是您想要做的事情吗?这个例子对您有用吗?
接口和类:
单元测试:
Revising my answer per your clarification. I don't disagree with arootbeer, but I do want to understand what you are doing and why it doesn't work.
Here's a simple example of what I think you are trying to do. The test passes for me for both concrete implementations. Is this what you are trying to do, and does this example work for you?
Interface and classes:
Unit test: