我正在使用。 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(), "");
}
}
我想念什么?
谢谢!
答案 0 :(得分:3)
您不应嘲笑您正在测试的类,而应嘲笑该类的依赖项,以更改它们产生的输出以及它们如何影响您正在运行的代码。单元测试应该只测试代码的单个逻辑位。
看一下有关如何模拟的简单教程:https://developerhandbook.com/unit-testing/writing-unit-tests-with-nunit-and-moq/
更新
我不认为您应该模拟数据库连接,要么将访问数据库内容的类抽象出来,然后对它进行模拟。
另一个问题是您正在使用哪种Db访问? EF?小巧的?有很多方法可以模拟这些,并测试您的类如何处理这些结果。
例如EF:
How to mock EntityFramework Database created by codefirst strategy?和How are people unit testing with Entity Framework 6, should you bother?
更新
您认为这是要调用真正的实现或基类实现是正确的。 但是,除非您尝试编写集成测试,否则它不适用于您的情况。如果编写单元测试,则应该独立于其他类的实际输出测试单个工作单元。我认为CallBase功能是另一个问题。以我的理解,它的意思是调用您从其继承的类以测试该功能,但仍然不应通过模拟实现该功能的类来对其进行测试,如果它是抽象类,则不应通过模拟该功能来对其进行测试。测试课程,否则您正在测试其他课程。要么更改该类,要么不对其进行测试,或者对原始类进行修改以调用该类并查看其输出。最重要的是,据我了解,您正在调用基础来模拟连接字符串或某种形式的连接,这对运行的代码没有影响,或者至少在模拟输出时不会如此,否则会已经进行集成测试。
要阅读的好文章是:http://www.codenutz.com/unit-testing-mocking-base-class-methods-with-moq/
答案 1 :(得分:0)
嘲笑很好。
我缺少的是在要测试的课程中将 RetrieveTranslations ()虚拟。
因此,以这种方式执行实际代码,除了RetrieveTranslations()方法之外,该方法将返回模拟告诉它返回的内容。