Questions tagged «mocking»

模拟和伪造是隔离代码或组件的方法,以确保单元测试仅针对可测试的代码单元运行,而无需实际利用其他组件或应用程序的依赖项。模拟与伪造的不同之处在于,可以检查模拟以断言测试结果。

4
什么时候应该使用模拟对象?
我已经阅读了很多有关TDD的内容,但是我仍然有疑问。例如,我有以下类图: 这是一个简单的示例,仅用于了解TDD和模拟对象。 我应该先写哪个测试?产品,然后行,最后,订购?如果这样做,我应该使用生产线和产品来测试订单还是应该使用模拟对象?我什么时候应该使用模拟对象?我应该在XP和TDD中使用UML吗? 我还没有这些东西。

1
如何对图像处理代码进行单元测试?
我正在图像处理(主要是OCR)方面工作,我想知道如何在开发中集成单元测试。 我已经在使用单元测试来处理更多“常见”类型的代码,但是在处理图像处理代码时,我不确定该如何处理。这种代码总是需要一些图像数据输入/输出,而对其进行模拟并不明显。目前,我主要进行集成测试,但是它们需要一段时间才能运行,我想了解一些有关如何将这种代码分解为单元测试的想法,以便我可以更快地运行它们。 编辑:分析角色可以经历许多步骤,包括多次旋转,缩放和形态操作。随着算法的发展,这些步骤经常改变。因此,在测试期间,输入和预期输出会发生很大变化。每个字符可以为100x100像素,因此毫无疑问地在代码中对它们进行编码或处理生成的数据。

4
如何测试依赖于复杂API(例如Amazon S3)的代码?
我正在努力测试一种将文档上传到Amazon S3的方法,但是我认为这个问题适用于任何非平凡的API /外部依赖。我只提出了三种潜在的解决方案,但似乎没有一个令人满意的: 请运行代码,实际上传文档,使用AWS的API检查文档是否已上传,然后在测试结束时将其删除。这将使测试非常缓慢,每次运行测试都将花费金钱,并且永远不会返回相同的结果。 模拟S3。这是超级毛茸茸的,因为我不知道该对象的内部,并且感觉太错了,因为它太复杂了。 只要确保使用正确的参数调用MyObject.upload(),并相信我正确使用了S3对象。这使我感到困扰,因为无法确定仅从测试中就正确使用了S3 API。 我检查了亚马逊如何测试他们自己的SDK,以及它们是否在模拟一切。他们有一个200行的助手来进行模拟。我觉得这样做不可行。 我该如何解决?
13 testing  mocking 

4
模拟是否违反开放/封闭原则?
前段时间,我在找不到的Stack Overflow答案上读了一句话,该句子解释您应该测试公共API,而作者说您应该测试接口。作者还解释说,如果更改了方法实现,则无需修改测试用例,因为这样做会破坏确保被测系统正常工作的契约。换句话说,如果方法不起作用,则测试应该失败,但这不是因为实现发生了变化。 当我们谈论嘲笑时,这引起了我的注意。由于模拟在很大程度上依赖于被测系统依赖项的期望调用,因此模拟与实现紧密相关,而不是与接口紧密相关。 在研究模拟与存根时,有几篇文章认为应该使用存根而不是模拟,因为它们不依赖于依赖项的期望,这意味着测试不需要了解测试实施中的基础系统。 我的问题是: 模拟是否违反开放/封闭原则? 在上一段中支持存根的论点中是否缺少某些内容,使存根与模拟不那么好? 如果是这样,什么时候可以模拟一个好用例,什么时候可以使用存根?

2
测试-内存中数据库与模拟
在编写测试时,为什么有人要使用内存数据库来模拟数据呢? 我可以看到内存数据库对于测试一个人的存储库可能是有益的。但是,如果使用框架(例如Spring Data),则测试存储库将测试框架,而不是测试应用程序逻辑。 但是,模拟似乎更快,并且遵循编写单元测试和TDD时通常采用的相同模式。 那我想念什么呢?何时/为什么内存数据库会受益?

3
如何用硬编码对象模拟方法?
我正在研究具有多层的应用程序。数据访问层从数据源检索和保存数据,业务逻辑处理数据,用户界面在屏幕上显示数据。 我还对业务逻辑层进行了单元测试。唯一的要求是测试业务层逻辑流。因此,我使用Moq框架来模拟数据访问层,并使用MS Unit对业务逻辑层进行单元测试。 我正在使用接口编程来使设计尽可能地分离,以便可以进行单元测试。业务层通过接口调用数据访问层。 当我尝试测试一种业务逻辑方法时,我遇到了一个问题。该方法完成了一些工作并创建了一个对象,并将其传递给数据访问层。当我尝试模拟该数据访问层方法时,则无法成功模拟。 在这里,我试图创建一个演示代码来显示我的问题。 模型: public class Employee { public string Name { get; set; } } 数据访问层: public interface IDal { string GetMessage(Employee emp); } public class Dal : IDal { public string GetMessage(Employee emp) { // Doing some data source access work... return string.Format("Hello {0}", emp.Name); …

3
模拟具体课程-不推荐
我刚刚读了《成长面向对象的软件》一书的摘录,其中解释了为什么不建议模拟具体类的一些原因。 以下是MusicCentre类的单元测试的一些示例代码: public class MusicCentreTest { @Test public void startsCdPlayerAtTimeRequested() { final MutableTime scheduledTime = new MutableTime(); CdPlayer player = new CdPlayer() { @Override public void scheduleToStartAt(Time startTime) { scheduledTime.set(startTime); } } MusicCentre centre = new MusicCentre(player); centre.startMediaAt(LATER); assertEquals(LATER, scheduledTime.get()); } } 和他的第一个解释: 这种方法的问题在于,它使对象之间的关系保持隐式。我希望我们现在已经弄清楚了,使用模拟对象进行测试驱动开发的目的是发现对象之间的关系。如果我是子类,则域代码中没有任何东西可以使这种关系可见,而只是对象上的方法。这使得很难看到支持这种关系的服务是否在其他地方有用,下次我与该类一起工作时,我将不得不再次进行分析。 他说的时候我无法确切知道他的意思: 这使得很难看到支持这种关系的服务是否在其他地方有用,下次我与该类一起工作时,我将不得不再次进行分析。 我了解该服务对应于MusicCentre称为的方法startMediaAt。 他在“其他地方”是什么意思? 完整的摘录在这里:http : …

1
“正当的做法”有多少嘲笑?
我开玩笑地为这个问题命名,因为我确定“取决于情况”,但是我有一些具体的问题。 在具有许多深层依赖项的软件中工作时,我的团队已经习惯了使用相当广泛的模拟将每个代码模块与其下的依赖项分开的习惯。 因此,令我惊讶的是Roy Osherove在此视频中建议您仅在5%的时间内使用模拟。我猜我们坐在70-90%之间。我也时常看到其他类似的指导。 我应该定义我认为是“集成测试”的两类,它们是如此不同,以至于它们实际上应该被赋予不同的名称:1)集成多个代码模块的进程内测试;以及2)进行对话的进程外测试。到数据库,文件系统,Web服务等。我关心的是类型#1,这些测试将所有代码模块都集成在进程中。 我阅读的许多社区指南都建议您应该使用大量独立的,细粒度的单元测试,以及少量的粗粒度的端到端集成测试,因为单元测试会为您提供有关确切位置的精确反馈可能已经创建了回归,但是设置繁琐的粗略测试实际上验证了系统的更多端到端功能。 鉴于此,似乎有必要经常使用模拟来隔离这些单独的代码单元。 给定一个对象模型,如下所示: ...还要考虑到我们应用程序的依赖深度比我在该图中适合的深度要深得多,因此在2-4层和5-13层之间有多层N。 如果我想测试在单元#1中做出的一些简单的逻辑决定,并且是否将每个依赖项都构造函数注入到依赖于它的代码模块中,例如将2、3和4构造函数注入到模块1中,图片,我宁愿将2、3和4的模拟物注入1。 否则,我将需要构造2、3和4的具体实例。这可能比仅仅进行一些额外的键入要困难得多。通常2、3和4会有构造器要求,要满足这些挑战可能很困难,根据图(并根据我们项目的实际情况),我将需要构造N到13的具体实例,以满足N的构造器。 2 3 3 当我需要2、3或4以某种方式运行时,这种情况变得更具挑战性,以便我可以测试#1中的简单逻辑决策。我可能需要一次理解整个对象图/树并“在逻辑上进行推理”,以使2、3或4以必要的方式运行。做myMockOfModule2.Setup(x => x.GoLeftOrRight())。Returns(new Right());通常看起来容易得多。当模块2告诉它正确时,测试模块1是否按预期响应。 如果我要一起测试2 ... N ... 13的具体实例,那么测试设置将非常大,并且几乎是重复的。测试失败可能无法很好地指出回归失败的位置。测试不会是独立的(另一个支持链接)。 当然,对底层进行基于状态的测试,而不是基于交互的测试,通常是合理的,因为这些模块很少具有任何进一步的依赖性。但似乎从定义上讲,模拟几乎是必要的,以隔离最底层之上的任何模块。 考虑到所有这些,谁能告诉我我可能会缺少什么?我们的团队过度使用模拟吗?还是在典型的单元测试指南中可能存在一些假设,即大多数应用程序中的依赖层将足够浅,因此测试集成在一起的所有代码模块确实是合理的(使我们的案例“特殊”)?或者,也许是不同的,我们的团队是否没有适当地限制我们有限的环境?

2
使用动态语言创建模拟时如何检测类型错误?
在执行TDD时会出现问题。经过几次测试通过后,某些类/模块的返回类型发生了变化。在静态类型的编程语言中,如果在其他某个类的测试中使用了先前的模拟对象,并且未对其进行修改以反映类型更改,则将发生编译错误。 但是,对于动态语言,可能无法检测到返回类型的更改,并且其他类的测试仍将通过。当然,可能会有集成测试稍后会失败,但是单元测试会错误地通过。有什么办法可以避免这种情况? 用一个简单的示例(在某些组合语言上)更新... 版本1: Calc = { doMultiply(x, y) {return x * y} } //.... more code .... // On some faraway remote code on a different file Rect = { computeArea(l, w) {return Calc.doMultipy(x*y)} } // test for Rect testComputeArea() { Calc = new Mock() Calc.expect(doMultiply, 2, 30) // …

5
TDD:模拟出紧密耦合的对象
有时只需要紧密耦合对象即可。例如,一个CsvFile类可能需要与CsvRecord该类(或ICsvRecord接口)紧密配合。 但是,从我过去的经验中学到,测试驱动开发的主要宗旨之一是“永远不要一次测试一个以上的类”。表示您应该使用ICsvRecord模拟或存根,而不是的实际实例CsvRecord。 但是,在尝试这种方法之后,我注意到嘲笑CsvRecord该类可能会变得有些毛茸茸。这使我得出以下两个结论之一: 编写单元测试很困难!那是代码的味道!重构! 模拟每个依赖项是不合理的。 当我用实际CsvRecord实例替换模拟对象时,事情进行得更加顺利。当寻找其他人的想法时,我偶然发现了这篇博客文章,该文章似乎支持上面的第二点。对于自然紧密耦合的对象,我们不必太担心模拟。 我会偏离轨道吗?以上假设2有不利之处吗?我是否真的应该考虑重构设计?
10 tdd  coupling  mocking 

1
函数样式如何帮助模拟依赖项?
摘自《 Java Magazine》最近一期对Kent Beck的采访: Binstock:让我们讨论微服务。在我看来,微服务的测试优先会变得复杂,因为某些服务要正常运行就需要大量其他服务。你同意吗? 贝克:上一堂大班或上几堂小班,似乎是一组折衷方案。 Binstock:是的,除了我猜,在这里,您必须使用大量的模拟程序,以便能够建立一个可以测试给定服务的系统。 贝克:我不同意。如果它是命令式样式,则必须使用很多模拟。在一种功能样式中,外部依赖项在调用链中被聚集在一起,那么我认为这不是必需的。我认为您可以从单元测试中获得很多覆盖。 他什么意思?函数样式如何使您摆脱对外部依赖的嘲笑?

4
如果从头开始设计易于使用TDD的新语言,会怎么样?
在使用某些最常见的语言(Java,C#,Java等)时,当您想要完全TDD代码时,有时似乎与该语言存在分歧。 例如,在Java和C#中,您将要模拟类的任何依赖关系,大多数模拟框架将建议您模拟接口而不是类。这通常意味着您有多个接口且只有一个实现(这种效果更加明显,因为TDD会迫使您编写大量较小的类)。让您正确模拟具体类的解决方案可以做一些事情,例如更改编译器或覆盖类加载器等,这很讨厌。 那么,如果从头开始设计一种对TDD来说很棒的语言,它将是什么样?可能是某种语言级别的方式来描述依赖项(而不是将接口传递给构造函数),并且能够不明确地分离类的接口?
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.