java中+存根是什么_伪造,嘲笑和存根之间有什么区别?

我知道我如何使用这些术语,但是我想知道是否存在接受伪造 , 模拟和存根的单元测试定义? 您如何为测试定义这些? 描述您可能会使用每种情况的情况。

这是我的用法:

Fake :实现接口但包含固定数据且没有逻辑的类。 只需根据实现返回“好”或“坏”数据。

Mock :一个实现接口并允许动态设置要返回的值/从特定方法抛出异常的类,并提供检查是否已调用/未调用特定方法的能力。

存根(Stub) :类似于模拟类,不同之处在于它不提供验证方法是否已被调用的能力。

模拟和存根可以手动生成,也可以由模拟框架生成。 伪类是手工生成的。 我主要使用模拟来验证我的类和依赖类之间的交互。 一旦验证了交互作用并测试了代码中的替代路径,便会使用存根。 我主要使用伪造的类来抽象出数据依赖性,或者当模拟/存根过于繁琐而无法每次设置时。

#1楼

让我感到惊讶的是,这个问题已经存在了很长时间,而且还没有人根据Roy Osherove的“单元测试的艺术”给出答案。

在“ 3.1介绍存根”中,将存根定义为:

存根是系统中现有依赖项(或协作者)的可控替代。 通过使用存根,您可以测试代码而无需直接处理依赖项。

并将存根和模拟之间的区别定义为:

关于模拟与存根之间要记住的主要事情是,模拟就像存根一样,但是您针对模拟对象断言,而您不针对存根进行断言。

虚假只是存根和模拟的名称。 例如,当您不关心存根和模拟之间的区别时。

Osherove区分存根和模拟的方式,意味着用作测试伪造品的任何类都可以是存根或模拟。 特定测试的内容完全取决于您如何在测试中编写检查。

当您的测试检查被测类中的值或除伪造品之外的其他任何地方时,伪造品被用作存根。 它只是提供了供被测类使用的值,可以直接通过调用返回的值来提供,也可以通过调用导致的副作用(在某些状态下)来间接提供。

当您的测试检查伪造品的值时,它被用作模拟。

使用FakeX类作为存根的测试示例:

const pleaseReturn5 = 5;

var fake = new FakeX(pleaseReturn5);

var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, cut.SomeProperty);

fake实例用作存根,因为Assert根本不使用fake 。

使用测试类X作为模拟的测试示例:

const pleaseReturn5 = 5;

var fake = new FakeX(pleaseReturn5);

var cut = new ClassUnderTest(fake);

cut.SquareIt;

Assert.AreEqual(25, fake.SomeProperty);

在这种情况下, Assert检查fake的值,使该假成为模拟。

现在,这些示例当然是非常人为设计的,但是我认为这种区别非常有价值。 它使您知道如何测试自己的东西以及测试的依赖关系在哪里。

我同意Osherove的观点

从纯粹的可维护性角度来看,在我的测试中,使用模拟比不使用模拟会带来更多的麻烦。 那是我的经验,但是我一直在学习新的东西。

断言是您真正要避免的事情,因为它使您的测试高度依赖于完全不是被测类的类的实现。 这意味着类ActualClassUnderTest的测试可以开始中断,因为ClassUsedAsMock的实现ClassUsedAsMock更改。 那给我散发出难闻的气味。 用于测试ActualClassUnderTest时最好只有突破ActualClassUnderTest改变。

我意识到写断言是对伪造的一种惯例,尤其是当您是TDD订户的嘲笑者类型时。 我想我与马丁·福勒(Martin Fowler)在古典主义阵营中坚定不移(请参阅马丁·福勒 ( Martin Fowler)的“模仿不是存根” (Ockserove not not Stubs )),并且像Osherove一样,尽可能避免进行交互测试(只能通过断言来进行测试)。

有趣的阅​​读,为什么你应该避免在这里定义的模拟,谷歌为“福勒模拟古典主义者”。 您会发现很多意见。

#2楼

您可以获得一些信息:

伪对象实际上具有有效的实现,但是通常采取一些捷径,这使它们不适合生产

存根提供对测试过程中进行的呼叫的固定答复,通常通常根本不响应为测试编程的内容。 存根还可以记录有关呼叫的信息,例如,电子邮件网关存根可以记住“已发送”的消息,或者仅记住“已发送”的消息数量。

嘲讽是我们在这里谈论的:带有期望的预编程对象,这些对象形成了期望接收的呼叫的规范。

伪造的 :我们获取或构建一种非常轻量级的功能,实现与SUT依赖的组件所提供的功能相同的功能,并指示SUT使用它而不是真实的。

存根(Stub) :此实现被配置为使用将执行SUT中未经测试的代码(请参阅第X页的生产错误)的值(或异常)响应来自SUT的调用。 使用测试存根的一个关键指示是由于无法控制SUT的间接输入而导致未测试代码

模拟对象 ,实现与SUT(被测系统)所依赖的对象相同的接口。 当我们需要进行行为验证时,可以将模拟对象用作观察点,以避免因无法观察调用方法对SUT的副作用而导致未经测试的需求(请参阅第X页的生产错误)。

亲身

我尝试通过使用简化:模拟和存根。 当它是一个返回设置为测试类的值的对象时,我会使用Mock。 我使用Stub模仿要测试的Interface或Abstract类。 实际上,您所说的并不重要,它们都是生产中不使用的类,并且用作测试的实用程序类。

#3楼

如果您熟悉Arrange-Act-Assert,那么解释存根和模拟之间的差异可能对您有用的一种方法是,存根属于安排部分,因为它们是用于排列输入状态的,而模拟属于断言部分,因为它们用于断言结果。

假人什么也没做。 它们仅用于填充参数列表,因此不会出现未定义或空错误。 它们也可以满足严格类型化语言中的类型检查器的要求,因此可以允许您编译和运行它们。

#4楼

为了说明存根和模拟的用法,我还要列举一个基于Roy Osherove的“ 单元测试的艺术 ”的示例。

想象一下,我们有一个LogAnalyzer应用程序,它具有打印日志的唯一功能。 它不仅需要与Web服务对话,而且如果Web服务引发错误,则LogAnalyzer必须将错误记录到其他外部依赖项中,并通过电子邮件将其发送给Web服务管理员。

这是我们要在LogAnalyzer中测试的逻辑:

if(fileName.Length<8)

{

try

{

service.LogError("Filename too short:" + fileName);

}

catch (Exception e)

{

email.SendEmail("a","subject",e.Message);

}

}

当Web服务引发异常时,如何测试LogAnalyzer正确调用电子邮件服务? 这是我们面临的问题:

我们如何替换Web服务?

我们如何模拟来自Web服务的异常,以便我们可以测试对电子邮件服务的呼叫?

我们如何知道电子邮件服务被正确调用或完全被调用?

通过使用Web服务的存根,我们可以处理前两个问题。 为了解决第三个问题,我们可以将模拟对象用于电子邮件服务 。

假货是一个通用术语,可以用来描述存根或模拟。在我们的测试中,我们将有两个假货。 一种将是电子邮件服务模拟,我们将使用它来验证是否已将正确的参数发送到电子邮件服务。 另一个将是一个存根,我们将使用它来模拟从Web服务引发的异常。 这是一个存根,因为我们不会使用伪造的Web服务来验证测试结果,只是为了确保测试正确运行。 电子邮件服务是一个模拟,因为我们会断言它已被正确调用。

[TestFixture]

public class LogAnalyzer2Tests

{

[Test]

public void Analyze_WebServiceThrows_SendsEmail()

{

StubService stubService = new StubService();

stubService.ToThrow= new Exception("fake exception");

MockEmailService mockEmail = new MockEmailService();

LogAnalyzer2 log = new LogAnalyzer2();

log.Service = stubService

log.Email=mockEmail;

string tooShortFileName="abc.ext";

log.Analyze(tooShortFileName);

Assert.AreEqual("a",mockEmail.To); //MOCKING USED

Assert.AreEqual("fake exception",mockEmail.Body); //MOCKING USED

Assert.AreEqual("subject",mockEmail.Subject);

}

}

#5楼

您在其中声明的东西称为模拟对象,而其他仅有助于测试运行的东西都是存根 。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值