什么时候在C#unit testing中使用模拟与伪装?
任何人都可以拿出指导方针,build议select嘲笑还是伪造的理想场景,即手动设置要领?
我对如何处理这种情况感到困惑。
那么你有几件事情你需要理清。 你有两个基本的东西你需要知道:命名和最佳实践。
首先,我想给你一个伟大的testing者,罗伊·奥谢罗夫伟大的video资源:
unit testing评论由Roy Osherove
他开始说他已经对几个开源项目附带的testing工具进行了一些评论。 你可以在这里find这些: http : //weblogs.asp.net/rosherove/archive/tags/TestReview/default.aspx
这些基本上都是video评论,他会带你通过这些testing用具,告诉你什么是好的,什么是坏的。 很有帮助。
罗伊也有一本我明白的书很好。
命名法
这个播客将帮助非常 : http : //www.hanselminutes.com/default.aspx? showID = 187
不过,我会用播客的话来解释一下(Hanselminutes介绍音乐是可怕的):
基本上,你用隔离框架 (如Moq,Rhino Mocks,Type Mock等)做的所有事情都叫做假货 。
伪造是在testing过程中使用的对象,您正在testing的代码可以调用代替生产代码。 伪造是用来隔离你正在testing的代码与你的应用程序的其他部分。
有(主要)两种types的假货 : 存根和嘲笑 。
模拟是一个假的,你放在适当的位置,以便你正在testing的代码可以调用它,并且你声明这个调用是用正确的参数进行的。 下面的示例使用Moq隔离框架来做到这一点:
[TestMethod] public void CalculateTax_ValidTaxRate_DALCallIsCorrect() { //Arrange Mock<ITaxRateDataAccess> taxDALMock = new Mock<ITaxRateDataAccess>(); taxDALMock.Setup(taxDAL => taxDAL.GetTaxRateForZipCode("75001")) .Returns(0.08).Verifiable(); TaxCalculator calc = new TaxCalculator(taxDALMock.Object); //Act decimal result = calc.CalculateTax("75001", 100.00); //Assert taxDALMock.VerifyAll(); }
一个存根与模拟几乎相同,不同之处在于你要确保你正在testing的代码从它的调用中获取一致的数据(例如,如果你的代码调用一个数据访问层,一个存根将返回假的数据),但是你不会对存根本身断言。 也就是说,您并不在意validation该方法是否称为您的假数据访问层 – 您正在尝试testing其他内容。 您提供了存根以获取您要testing的方法以独立工作。
这是一个存根的例子:
[TestMethod] public void CalculateTax_ValidTaxRate_TaxValueIsCorrect() { //Arrange Mock<ITaxRateDataAccess> taxDALStub = new Mock<ITaxRateDataAccess>(); taxDALStub.Setup(taxDAL => taxDAL.GetTaxRateForZipCode("75001")) .Returns(0.08); TaxCalculator calc = new TaxCalculator(taxDALStub.Object); //Act decimal result = calc.CalculateTax("75001", 100.00); //Assert Assert.AreEqual(result, 8.00); }
注意,我们正在testing方法的输出,而不是方法调用另一个资源的事实。
Moq实际上并没有在模拟和存根之间做出区别(注意两者都被声明为
Mock<T>
),但是这里的用法在确定types时很重要。
希望这有助于你的直线。
有5种不同的testing双打:假人,短线,嘲笑,间谍和假货。 http://code.google.com/testing/TotT-2008-06-12.pdf中有一个很好的概述,它们也分为http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and% 20Dummies.html
你想testing一个代码块,对,让我们来说一个方法。 您的方法从http url下载文件,然后将该文件保存在磁盘上,然后将该文件发送到磁盘上。 所有这三个动作当然都是你的方法调用的服务类,因为这样他们很容易被嘲笑。 如果你不嘲笑这些,你的testing会下载东西,访问磁盘,并且每次运行testing时都会收到邮件。 那么你不仅仅是testing方法中的代码,你还在testing下载,写入磁盘和发送邮件的代码。 现在,如果你嘲笑这些,你只是testing方法代码。 你也可以模拟一个下载失败的例子,看看你的方法的代码行为是否正确。
至于伪装,我通常假冒那些只是持有价值的类,并没有太多的逻辑。 如果你发送一个包含一些值的对象,在方法中被修改,你可以在testing中读取它,看看这个方法是否正确。
当然,这些规则可以(有时也必须)稍微弯曲,但一般的思维方式是testing你的代码,只testing你的代码。
来自鲍勃·马丁(Bob Martin) 的小嘲笑者(Little Mocker)在这个话题上是非常好的读物。
[…]很久以前,一些非常聪明的人写了一篇文章,介绍和定义了“模拟对象”这个词。 很多其他人阅读并开始使用这个术语。 其他没有读过这篇文章的人听到这个词,开始使用这个术语的意思更为广泛。 他们甚至把这个词变成动词。 他们会说:“让我们嘲笑这个对象”,或者“我们有很多嘲弄的事情要做”。
文章解释了嘲笑,假货,间谍和存根之间的区别。