Junit4: 增强功能:BigDecimal 支持 assertEquals()

创建于 2010-03-25  ·  27评论  ·  资料来源: junit-team/junit4

使用 JUnit 来测试 BigDecimal 值总是一个痛点。 这是因为 BigDecimal 使用 equals() 考虑精度,但在 compareTo() 中忽略它。 处理此问题的最佳方法是使用新的 assertEquals 方法,该方法允许选择性地评估精度。 您还可以添加接受消息的替代方法:

public static void assertEquals(预期的BigDecimal,实际的BigDecimal,布尔值precisionMatters){
如果(精度问题){
Assert.assertEquals(预期,实际);
} 别的 {
Assert.assertEquals(0, expected.compareTo(actual));
}
}

feature

最有用的评论

您是否尝试过使用comparesEqualTo

所有27条评论

作为叉子或补丁放在一起将是一件容易的事情; 如果合适,我愿意这样做。

我宁愿有一个 assertNumericallyEqualTo 断言而不是传递给 assertEquals 的布尔标志。

这是个好名字。 我会将其缩短为 assertNumericallyEquals()。

虽然我同意这种观点,但我不确定使用不同名称的另一种断言方法是否真的有助于消除混淆,尤其是在完全不知道差异或自己没有真正遇到问题的人中。 我的意思是,如果我没有读过这个问题,我会继续使用assertEquals()来代替BigDecimal 。 在一般情况下,它实际上会像宣传的那样工作——它完全按照BigDecimal#equals()工作方式工作。 我什至会争辩说这是一件好事——它迫使人们意识到BigDecimal#equals()比较了价值和规模,然后也许这不是他们想要实现的目标——不过,在其他情况下,我认为它_是_。 我的意思是,在某些情况下,我们想要检查方法返回的实际值是否与预期值 _exactly_ '相等'(不仅仅是逻辑/数字相等)。 换句话说: assertNumericallyEquals()提供了什么(除了简洁) assertEquals(0, actual.compareTo(expected))没有提供? 就我个人而言,如果我经常需要它,我可能会创建一个 Hamcrest 匹配器并使用assertThat(actual, isNumericallyEqualTo(expected)) - 此外,可以在任何可以使用 Hamcrest 匹配器的地方使用(数据验证等)。

抱歉,称重晚了,但我个人的意见与 Alistair 的意见相近。

换句话说: assertNumericallyEquals()提供了什么(除了简洁) assertEquals(0, actual.compareTo(expected))没有提供?

更清楚地传达意图? hamcrest matcher 方法对我来说很好。

杰弗里,

您是说您可以为自己的项目编写匹配器,还是希望它与 hamcrest 一起提供? 或 JUnit,但不是 hamcrest?

以上任何一项或全部——我编写的大多数项目最终都有一些自定义的 hamcrest 匹配器。 Hamcrest 和/或 JUnit 涵盖的常见案例可以节省一点时间,但这对我来说也不是一个非常常见的案例。

关于不太有用的错误消息的一点。我刚刚将我的 Assert.assertEquals 调用转换为 Assert.assertTrue,在比较 BigDecimals 和 Assert.assertEquals 时遇到了失败。 当然,现在我的测试失败了,出现了一种“布尔测试失败”的错误,没有告诉我这些值是什么。 以同样的方式,assertEquals(0, actual.compareTo(expected)) 会记录例如“expected 0 but got: 1”,当一条更有用的错误消息来自 assertNumericallyEquals(actual, expected) 将是“expected 12.45 but got : 123"('actual' 和 'expected' 参数的实际值)。

http://www.bssd.eu/blog/?p=113阅读起来也很有趣。

来自https://github.com/KentBeck/junit/pull/228 的assertEquivalent 应该可以解决这个问题。

谢谢dsaff。 那件作品看起来很棒。 我以前没有这样做过,这是否意味着我必须获取 junit 源,自己合并这个拉取请求,然后进行自定义构建?

http://help.github.com/send-pull-requests/的帮助看来,我应该:

git 克隆https://github.com/KentBeck/junit.git
cd junit

然后为拉取请求添加一个遥控器,然后获取、合并或两者都做。

鉴于这似乎是一个拉取请求,即不是官方的 junit,在应用程序中使用是否明智? 这是否有可能在主要junit之外成型,并且我将我的代码发送给其他人时会遇到问题,而不会为谁构建?

尼克芬维克

是的,您现在正走在正确的道路上。 我打算将那个 pull 合并到 4.10 分支中,但原作者在让 git status 变得可合并时遇到了麻烦。 如果你有时间帮个忙,你可以 fork KentBeck repo,合并所有内容,并针对 4.10 分支发出拉取请求,这样每个人都会更容易(如果它听起来很流行,我什至可以旋转有时会出现一个 4.10 预览 jar)。

我以前真的从来没有这样做过:) 所以我已经分叉了 repo 并将[email protected] :neekfenwick/junit.git 克隆到我的本地机器(我已经有一个 github 帐户和 ssh 密钥设置),并添加我从中分叉的 repo 的遥控器:

git remote add upstream https://github.com/KentBeck/junit.git

只是为了更好地衡量,我已经分支,所以我可以将拉取请求合并到 HEAD 以外的其他地方:

git branch merge_pullreq_228
git checkout merge_pullreq_228

现在我可以找到的文档说“现在将拉取请求合并到您的分支中”。 我可以在https://github.com/KentBeck/junit/pull/228/commits看到 pull 228 的提交,但我无法合并它们:

[neek junit (merge_pullreq_228)]$ git merge 57b49344
fatal: '57b49344' does not point to a commit

由于拉取请求不是针对我自己的存储库/分支,因此我无法使用 github web gui (AFAIK) 中的合并工具。

我认为您希望我将 7 个提交合并到我自己的分支中并让它构建/通过单元测试是否正确? 您能否说明如何合并这些提交之一以使我继续前进?

是的,您不能使用网络合并工具。 我认为应该起作用的是:

git 远程添加 leet3lite https://github.com/leet3lite/junit.git

然后从你的分行,打电话

git pull leet3lite 大师

不幸的是,在描述如何“通过电话”使用 git 时,我通常会忘记一件事,所以请告诉我这是否适合您。

啊,我明白了,我不需要合并每个提交.. leet3lite 的 master 分支已经有了它们,将这些工作合并到原始 master 的行为就是问题所在。

该分支和 HEAD 之间似乎存在合并冲突。 我想这就是这个练习的全部意义所在。

[neek junit (merge_pullreq_228)]$ git remote add leet3lite https://github.com/leet3lite/junit.git
[neek junit (merge_pullreq_228)]$ git pull leet3lite master
remote: Counting objects: 100, done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 85 (delta 34), reused 77 (delta 26)
Unpacking objects: 100% (85/85), done.
From https://github.com/leet3lite/junit
 * branch            master     -> FETCH_HEAD
Auto-merging acknowledgements.txt
CONFLICT (content): Merge conflict in acknowledgements.txt
Auto-merging src/main/java/org/junit/Assert.java
Auto-merging src/test/java/org/junit/tests/AllTests.java
CONFLICT (content): Merge conflict in src/test/java/org/junit/tests/AllTests.java
Automatic merge failed; fix conflicts and then commit the result.
[neek junit (merge_pullreq_228|MERGING)]$ 

如果你觉得这很明智,我明天会考虑继续这样做。 这里快午夜了。

看来您来对地方了。 acknowledgements.txt 和 AllTests.java 接触了很多,通常只是添加,所以合并操作可能是一个简单的操作,包括在两个路径上添加的所有行。

非常感谢您推动这一进程。

我认为这是 2 年前修复的。

dsaff——没有……?

不是 4.11 ;( 我也需要这个功能

关于assertEquivalent()的讨论移至 #228,之后,我认为它移至 #376,我们决定真正的 Hamcrest 应该解决这个问题。

@junit-team/junit-committers 对我关闭这个有什么异议吗?

我这边没有异议。

哎呀,弗洛伊德点击。 :-) 这里没有异议。

好的。 那就关门了。

我认为使用 hamcrest 匹配器不能解决这个问题。 例如这段代码:

   assertThat(product.getRating(), is(equalTo(new BigDecimal("2.3"))));

会产生这样的结果:

Expected: is <2.3>
     but: was <2.30000>

我认为 junit 或 hamcrest 仍然需要isNumericEquivalent方法。

您是否尝试过使用comparesEqualTo

是的, comparesEqualTo确实有效。 谢谢。

这是我前段时间创建的备忘单:
http://www.marcphilipp.de/blog/2013/01/02/hamcrest-quick-reference/

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

lvc picture lvc  ·  6评论

bigmikef picture bigmikef  ·  39评论

kcooney picture kcooney  ·  108评论

sbrannen picture sbrannen  ·  22评论

apreg picture apreg  ·  4评论