2009-08-18 73 views
4

我正在使用System.Data.DataSet前面的接口(IDataSet)进行测试。我希望能够模拟Copy()方法。基本上我想要一个相同的模拟对象的副本/克隆。有没有办法按值复制Moq Mock <>?

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

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

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

这可能吗?

回答

4

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

这意味着必须告诉它它的Copy方法是如何工作的。如果你这样做是的implmementation以下,复制方法有:

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类,像你希望它表现实现复制方法(即不是作为抽象或虚拟方法)。
  • 而不是创建一个IDataSet的模拟,使用假。假是接口的特定测试实现,其行为接近真实。没有创建假货的框架/库,所以你需要手动编写这样的假货。
  • 请考虑Copy方法是否应该真的成为接口的一部分。在我看来,这是一个不属于界面的实现细节。

您可以在优秀的书xUnit Test Patterns中阅读有关存根,嘲笑,假货和其他单元测试设计模式的内容。

+0

感谢您的洞察。将“dataMock”切换到假冒让我走出了死亡之路。 – 2009-08-18 20:43:29

+0

+1 - 很好的答案!我会争辩说,Moq允许您创建Fakes,因为您可以执行Return(Func)或Callback(Action)。但手动伪装可能更具可读性。 – TrueWill 2010-03-05 13:53:04

+1

@TrueWill:这是一个有效的观点,但最重要的是它展示了我在另一个环境中所做的一点:测试双打居住在一个模糊定义的连续体中:http://msdn.microsoft.com/en-us/magazine/cc163358.aspx – 2010-03-05 13:58:00

相关问题