什么时候在C#单元测试中使用mocking和faking?

时间:2009-09-14 04:46:22

标签: c# .net unit-testing tdd

任何人都可以提出指导方案,建议选择嘲讽与假装的理想方案,即手动设置必需品吗?

我对如何应对这种情况感到困惑。

4 个答案:

答案 0 :(得分:83)

嗯,你有一些事情需要解决。您需要知道两件基本事项:命名法和最佳实践。

首先,我想给一位伟大的测试人员Roy Osherove提供一个很棒的视频资源:

Roy Osherove的单元测试评论

  

他开始说他有   做了一些测试工具的评论   与几个开源一起发货   项目。你可以在这里找到:   http://weblogs.asp.net/rosherove/archive/tags/TestReview/default.aspx

     

这些基本上是视频评论   他带领你完成这些测试   利用并告诉你什么是好的   什么是坏事。非常有帮助。

     罗伊还有一本我理解的书   非常好。

<强>命名法

  

此播客将有所帮助   非常http://www.hanselminutes.com/default.aspx?showID=187

     但是,我会解释播客   (Hanselminutes介绍音乐是   可怕):

     

基本上你做的一切都是   隔离框架(如Moq,Rhino Mocks,Type Mock等)被称为a   

     

是一个正在使用的对象   测试您正在测试的代码   可以代替生产代码。   伪造用于隔离您的代码   正试图从其他部分进行测试   你的申请。

     

(主要)有两种类型的假货存根   和模拟

     

模拟是你输入的假货   放置以便您正在测试的代码   可以呼唤它,你断言   电话是正确的   参数。以下示例就是这样做的   这使用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();
}
     

存根与a几乎相同   嘲笑,除非你把它放到位   确保您正在测试的代码   从中获取一致的数据   调用(例如,如果您的代码调用   数据访问层,存根会   返回假数据),但你没有   断言存根本身。那   是的,你不在乎验证   称为假数据访问的方法   图层 - 您正在尝试测试   别的。你提供存根   获得你想要的方法   测试工作孤立。

     

以下是存根的示例:

[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);
}
     

请注意我们正在测试   方法的输出,而不是   事实上,该方法拨打了电话   另一种资源。

     

Moq并没有真正制作API   模拟和存根之间的区别   (注意两者都被宣布为   Mock<T>),但这里的用法是   在确定类型时很重要。

希望这有助于让你顺利。

答案 1 :(得分:17)

至少有5种不同的测试双打:假人,残茬,嘲笑,间谍和假货。好的概述位于http://code.google.com/testing/TotT-2008-06-12.pdf,它们也归类为http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html

答案 2 :(得分:1)

你想测试一大块代码,对吧,让我们说一个方法。您的方法从http url下载文件,然后将文件保存在磁盘上,然后将该文件发送到磁盘上。所有这三个操作当然都是您的方法调用的服务类,因为它们很容易被模拟。如果你不模仿这些,你的测试将下载东西,访问磁盘,并在每次运行测试时发送邮件。然后,您不仅要测试方法中的代码,还要测试下载,写入磁盘和发送邮件的代码。现在,如果您正在嘲笑这些,那么您只是在测试方法代码。此外,您还可以模拟下载失败,以查看方法的代码是否正常运行。

现在至于假装,我通常会假装只持有值的类,并且没有太多逻辑。如果您要发送一个包含某些值的对象,并在方法中进行更改,则可以在测试中读取它以查看该方法是否正确。

当然规则可以(有时必须)稍微弯曲一下,但一般的思维方式是测试你的代码和你的代码。

答案 3 :(得分:1)

来自鲍勃·马丁的

The Little Mocker对这个话题非常好。

  

[...]很久以前,一些非常聪明的人写了一篇论文,介绍并定义了Mock Object一词。很多其他人阅读并开始使用该术语。其他没有阅读过论文的人听到了这个词,并开始使用它具有更广泛的意义。他们甚至把这个词变成了动词。他们会说,&#34;让我们嘲笑那个对象。&#34;或者&#34;我们有很多嘲笑要做。&#34;

文章解释了模拟,假货,间谍和存根之间的区别。