- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有以下挑战,但我还没有找到好的答案。我正在使用 Mocking 框架(在本例中为 JMock)以允许将单元测试与数据库代码隔离。我正在模拟对涉及数据库逻辑的类的访问,并使用 DBUnit 单独测试数据库类。
我遇到的问题是我注意到一种模式,其中逻辑在多个地方概念上重复。例如,我需要检测数据库中的值不存在,因此在这种情况下我可能会从方法返回 null。所以我有一个数据库访问类,它执行数据库交互,并适本地返回 null。然后我有业务逻辑类,它从模拟中接收空值,然后如果值为空值则进行测试以采取适当的行动。
现在,如果将来该行为需要更改并且返回 null 不再合适,例如因为状态变得更加复杂,所以我需要返回一个报告该值不存在的对象以及来自数据库。
现在,如果我将数据库类的行为更改为在这种情况下不再返回 null,则业务逻辑类仍会显示为正常运行,并且该错误只会在 QA 中被捕获,除非有人记得耦合,或正确遵循方法的用法。
我觉得我遗漏了一些东西,必须有更好的方法来避免这种概念上的重复,或者至少对其进行测试,以便如果它发生更改,则更改未传播的事实无法通过单元测试。
有什么建议?
更新:
让我试着澄清我的问题。我在考虑当代码随着时间的推移而演变时,如何确保通过模拟测试的类和模拟所代表的类的实际实现之间的集成不会中断。
例如,我刚刚有一个案例,我有一个最初创建的方法并且不期望空值,所以这不是对真实对象的测试。然后类的用户(通过模拟测试)被增强为在某些情况下传入一个 null 作为参数。在集成失败时,因为没有对真正的类进行 null 测试。现在,当最初构建这些类时,这没什么大不了的,因为您在构建时正在测试两端,但是如果设计需要在两个月后演变而您往往会忘记细节,那么您将如何测试之间的交互?这两组对象(通过模拟与实际实现测试的对象)?
潜在的问题似乎是重复(即违反 DRY 原则)之一,期望确实保留在两个地方,虽然关系是概念上的,但没有实际的重复代码。
[在 Aaron Digulla 对他的回答进行第二次编辑后进行编辑]:
对,这正是我正在做的事情(除了通过 DBUnit 测试并在测试期间与数据库交互的类中与 DB 进一步交互,但它是相同的想法)。所以现在,假设我们需要修改数据库行为,以便结果不同。使用模拟的测试将继续通过,除非 1)有人记得或 2)它在集成中中断。因此,数据库的存储过程返回值(比如说)在模拟的测试数据中基本上是重复的。现在让我烦恼的是重复逻辑是重复的,这是对 DRY 的微妙违反。可能就是这样(毕竟集成测试是有原因的),但我觉得我错过了一些东西。
[编辑开始赏金]
阅读与 Aaron 的互动达到了问题的重点,但我真正想要的是对如何避免或管理明显重复的一些见解,以便真实类(class)行为的变化将显示在与模拟交互的单元测试作为破坏的东西。显然这不会自动发生,但可能有一种方法可以正确设计场景。
[编辑奖励赏金]
感谢所有花时间回答问题的人。获胜者教会了我一些关于如何思考如何在两层之间传递数据的新知识,并首先得到了答案。
最佳答案
你从根本上要求不可能的事情。您要求您的单元测试在您更改外部资源的行为时预测并通知您。不编写测试来产生新行为,他们怎么知道?
您所描述的是添加一个必须进行测试的全新状态 - 而不是空结果,现在有一些对象从数据库中出来。你的测试套件怎么可能知道被测对象的预期行为对于一些新的随机对象应该是什么?您需要编写一个新的测试。
正如您评论的那样,模拟不是“行为不端”。模拟正在做你设置它要做的事情。规范更改的事实对模拟没有影响。这种情况下唯一的问题是实现更改的人忘记更新单元测试。我实际上不太确定为什么您认为存在任何重复的担忧。
向系统添加一些新返回结果的编码器负责添加单元测试来处理这种情况。如果该代码也 100% 确定现在不可能返回空结果,那么他也可以删除旧的单元测试。但你为什么要这样做?单元测试正确地描述了被测对象在收到空结果时的行为。如果将系统后端更改为某个确实返回空值的新数据库,会发生什么情况?如果规范变回返回 null 怎么办?您不妨保留测试,因为就您的对象而言,它确实可以从外部资源中取回任何东西,并且应该优雅地处理所有可能的情况。
模拟的全部目的是将您的测试与真实资源分离。它不会自动使您免于将错误引入系统。如果您的单元测试准确地描述了接收空值时的行为,那太好了!但是这个测试不应该知道任何其他状态,当然也不应该以某种方式被告知外部资源将不再发送空值。
如果您进行适当的松散耦合设计,您的系统可以拥有您能想象到的任何后端。您不应该只考虑一种外部资源来编写测试。如果您添加一些使用真实数据库的集成测试,从而消除模拟层,听起来您可能会更高兴。这对于进行构建或健全性/烟雾测试始终是一个好主意,但通常会阻碍日常开发。
关于unit-testing - 如何使用 Mocks 避免重复逻辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/643410/
我有以下功能: fun process(t: T, call: (U) -> Unit, map: (T) -> U) = call(map(t)) fun processEmpty(t: T,
关闭。这个问题需要更多focused .它目前不接受答案。 想改善这个问题吗?更新问题,使其仅关注一个问题 editing this post . 4年前关闭。 Improve this questi
我正在实现 SVG Tiny 1.1,但我无法理解“用户单元”的概念。 SVG 1.1 规范将每个没有指定单位(例如“mm”、“cm”、“pt”等)的 定义为“用户单位”。 在实现接口(interfa
我正在学习本教程 - http://blog.dasberg.nl/getting-your-frontend-code-quality-in-order/ - 将前端质量指标推送到 SonarQub
我用了 rails new app --skip-test-unit 因为最初,我认为我可以稍后添加测试。 我开发了我的应用程序的很大一部分。 现在,我想添加 Test::Unit 但我找不到任何有关
您如何对由某些报表引擎(例如Crystal Reports或SQL Server Reporting Services)创建的报表进行“单元测试”? 最佳答案 报告的问题类似于GUI的问题。 如果报表
今天在 Proggit 上,我正在阅读题为“Why Unit Testing Is A Waste of Time”的提交的评论线程。 我并不真正关心文章的前提,而是关心 comment对此作出: T
“单元测试”属于白盒测试还是黑盒测试?还是与其他两种测试完全不同? 最佳答案 我觉得这个article by Kent Beck更多地引用 TDD 和单元测试很好地总结了这一点。基本上,这取决于您实际
这是代码: def filterAcc(p: Tweet => Boolean, acc: TweetSet): TweetSet = { foreach(tweet => if(p(el
我打算编写一个抽象类来测试我所有的 DTO 和 DOMAIN 对象。此类将采用可模板对象(通用类型)并使用反射来获取其中的属性类型,并将一些默认值分配给标识的原始类型,稍后将通过访问它们来断言这些类型
我有一个像这样的简单容器特征: trait Handler { def apply[In, Out](in: In): Out } 当我尝试实现它时: new Handler { def ap
为什么这样编译 scala> import scala.concurrent.Future import scala.concurrent.Future scala> val f: Unit = Fu
您使用什么样的实践来使您的代码对单元测试更加友好? 最佳答案 TDD——首先编写测试,强制你要考虑可测试性和帮助编写实际的代码需要的,而不是你认为可能的需要 接口(interface)重构——使得 m
我在elasticsearch中有文本字段,我想在kibana上可视化词云... 第一步,我们需要标记它们,我使用了“标准标记器” ... 使用这种形式的词云可视化结果如下图所示: 但是我需要的是专有
我有以下方法: override def insertAll(notifications: Seq[PushNotificationEncoded]) (i
我的应用程序服务层中有很多方法正在做这样的事情: public void Execute(PlaceOrderOnHoldCommand command) { var order = _rep
一直在使用 Sails.js,但在为 Controller 设计 Jasmine 单元测试时遇到了麻烦。如果这很明显,请原谅我的无知,因为在过去的 3-4 个月里我才深入研究 JavaScript 开
Closed. This question does not meet Stack Overflow guidelines。它当前不接受答案。 想改善这个问题吗?更新问题,以便将其作为on-topic
在ReKotlin repo README中,有如下代码: data class CounterActionIncrease(val unit: Unit = Unit): Action 代码Unit
我想对一个业务类进行测试,但我遇到了这个问题:其中一个模拟对象与其他类(例如 Sites、URL 和 ComplexObject)有许多依赖关系。 我的问题是:如果我必须在需要测试的方法中使用我的模拟
我是一名优秀的程序员,十分优秀!