有没有办法复制Moq Mock<>按价值?

时间:2009-08-18 17:38:26

标签: c# moq

我在System.Data.DataSet前面使用接口(IDataSet)进行测试。我希望能够模拟Copy()方法。基本上我想要一个同一个模拟对象的副本/克隆。

这是我想要做的一些伪代码。

Mock<IDataSet> dataMock = new Mock<IDataSet>();
Mock<IDataSet> copyMock = ???    // How do I clone the mock?

dataMock.Setup(c => c.Copy()).Returns(copyMock.Object);

这可能吗?

1 个答案:

答案 0 :(得分:4)

基本上,模拟不是真实的,所以它没有真实的行为。它不应该有真正的行为 - 它应该做任何你告诉它的事情,同时跟踪发生的事情。没有更多,也没有更少。

这意味着必须告诉它它的Copy方法是如何工作的。如果您执行以下操作, 复制方法将具有的实施内容:

Mock<IDataSet> dataMock = new Mock<IDataSet>();
Mock<IDataSet> copyMock = new Mock<IDataSet>();

dataMock.Setup(c => c.Copy()).Returns(copyMock.Object);

但是,你也可以这样做:

Mock<IDataSet> dataMock = new Mock<IDataSet>();
Mock<IDataSet> copyMock = dataMock;

dataMock.Setup(c => c.Copy()).Returns(copyMock.Object);
然后,

成为Copy方法的实现。请记住:接口不是合同,说明方法应该做什么;它只定义了方法的签名。

您可能希望将数据从一个IDataSet复制到另一个IDataSet,但请记住Mock是纯粹的行为;它没有数据。

您可以考虑以下几种方法:

  • 将IDataSet替换为抽象的DataSetBase类,并按照您希望它的行为实现Copy方法(即作为抽象或虚拟方法)。
  • 使用假冒,而不是创建IDataSet模拟。假冒是一种特定于测试的实现接口,其行为接近真实的行为。没有用于创建Fakes的框架/库,因此您需要手动编写这样的伪造。
  • 考虑Copy方法是否真的应该成为界面的一部分。听起来我觉得这是一个不属于接口的实现细节。

您可以在优秀的书籍xUnit Test Patterns中阅读Stubs,Mocks,Fakes和其他单元测试设计模式。