【发布时间】:2019-10-03 07:30:23
【问题描述】:
我正在使用 .CallBase() 来执行 TsExporter 类中 .Export() 方法的模拟背后的真实代码。
另一方面,.RetrieveTranslations() 也在执行真正的代码,而不是像“我告诉它这样做”那样返回模拟值。
代码如下:
[TestFixture]
public class TestClass
{
private Mock<ITsExporter> _tsExporter;
[SetUp]
public void SetUp()
{
_tsExporter = new Mock<TsExporter>().As<ITsExporter>();
//This is calling the real code which is good
_tsExporter.Setup(x => x.Export(It.IsAny<TsFileModel>(), It.IsAny<string>()))
.CallBase();
//but this is calling the real code too, and I was expecting not to
//call it and return the mock instead...
_tsExporter.Setup(x => x.RetrieveTranslations(It.IsAny<DataTable>(),
It.IsAny<string>(), It.IsAny<string>()))
.Returns(new DataTable());
}
[Test]
public void Test()
{
_tsExporter.Object.Export(new TsFileModel(), "");
}
}
我错过了什么?
谢谢!
【问题讨论】:
-
你用错了
Mocks。查看this blog 以了解如何为单元测试和模拟设计代码。基本上,您注入外部依赖项(ITsExporter),父类将调用您的模拟对象而不是真实对象。 -
不幸的是,我认为情况并非如此,如果我错了,请纠正我:我没有任何外部依赖项。只有这个类 TsExporter 实现和接口 ITsExporter。方法 Export() 将从其他地方调用(带有一些参数), RetrieveTranslations() 由 Export() 方法在内部调用,这会创建一个数据库连接,这就是我想模拟这个方法的原因,它将是在我们使用数据库的集成测试中进行了测试。我希望这是有道理的。我不想模拟数据库连接,还是应该模拟?
-
你正在创建一个数据库连接,所以你有一个外部依赖。为了模拟该外部依赖项,您应该以可以模拟该外部依赖项的方式对代码进行建模,即模拟数据库连接(或用于访问数据库的抽象)。
-
另外,查看您的代码,
Export的设置是毫无意义的,因为它所做的一切CallBase()。您不妨删除它,因为_tsExporter.Object.Export(...)无论如何都会调用真实方法。嘲笑它,你一无所获。而且,当您移动它时,您可能会看到为什么您的模拟RetrieveTranslations没有被调用?提示:您只是在调用不了解您的模拟的真正类:-) -
感谢您的回答!如果我将其删除,它将不再调用真实代码,它将模拟所有内容。