gpt4 book ai didi

java - 使用模拟验证错误消息,其中结果可以根据 id 更改

转载 作者:行者123 更新时间:2023-12-01 11:00:21 25 4
gpt4 key购买 nike

所以我有一些单元测试,我在其中模拟许多对象,并使用它们来编写测试。

我正在使用 anyInt() 参数匹配器设置模拟对象。我想验证一个名为 displayErrorMessage(String errorMsg) 的方法。此方法接受一个字符串,并将其输出到 GUI 中。它接受的字符串在发送到带有相关成员 ID 的显示方法之前会被格式化。

我想再次以字符串格式使用参数匹配器,将正确的错误消息传递给验证语句。

String.format("Member %d cannot borrow at this time.", anyInt());

我知道 anyInt() 返回零。我可以手动验证 displayErrorMessage() 假设这一点,但这似乎不正确。

当前测试代码:

@Test
public void borrowingRestrictedWhenCardSwipedHasExceededFineLimit() throws Exception {
when(memberDAO.getMemberByID(anyInt())).thenReturn(member);
when(member.hasReachedFineLimit()).thenReturn(true);

ctl.initialise();
ctl.cardSwiped(anyInt());

String errorMessage = "Member %d cannot borrow at this time.";
errorMessage = String.format(errorMessage, anyInt());

verify(ui).displayErrorMessage(errorMessage);
}

此验证在这种情况下有效:

verify(ui).displayErrorMessage("成员(member)0此时无法借阅。");

如果我的方法不正确,有什么更好的方法吗?

最佳答案

由于这个解释有点长,这里是一个答案......

anyInt() 在需要匹配时用作参数。主要有两种情况:

when( myMock.someMethod( anyInt() ).thenReturn( x );

这使得 myMock 在调用 someMethod 时返回“x” - 无论所讨论的实际 int 是什么。所以...

myMock.someMethod( 12 ) // will return x
myMock.someMethod( -180 ) // will return x
myMock.someMethod( 42 ) // will return x
// etc. ANY int parameter you give, will lead to x, since you told Mockito so in the when statement.

使用它的另一种方法是验证:

verify(myMock, times(1)).someMethod( anyInt() );

如果从未使用任何 int 调用 someMethod,则只会抛出错误。如果它是用 12 或 -180 或 42 或 1 或 2 或 3 等来调用的,那就没问题(只要它被调用一次——不是每个 int 一次,而是总共一次)。

当然,anyInt() 有一个 int 值,因为它必须放入 int 的位置,但我会完全忽略该值并且从不依赖它。

当最后调用真正的方法时,你不应该使用anyInt(),而应该使用真正的值,因为这会给你更多的控制权。就你而言,老实说,我根本不会使用anyInt():

@Test
public void borrowingRestrictedWhenCardSwipedHasExceededFineLimit() throws Exception {
when(memberDAO.getMemberByID(42)).thenReturn(member);
when(member.hasReachedFineLimit()).thenReturn(true);

ctl.initialise();
ctl.cardSwiped(42);

String errorMessage = "Member %d cannot borrow at this time.";
errorMessage = String.format(errorMessage, 42);

verify(ui).displayErrorMessage(errorMessage);
}
为什么?因为这样您就可以确定,当调用 ctl.cardSwiped 时,它实际上会使用 memberDAO.getMemberByID 调用的参数。使用anyInt() 则不能。例如, ctl.cardSwiped 中可能存在错误:

memberDao.getMemberById( parameter - 1);

在您的when中使用anyInt(),您的结果仍然是成员。

您知道您的测试用例将给出 42 作为参数,并且仅当给出 42 时,您才想返回该成员。所以你测试给定的参数实际上是用于内部(memberDao)对象的调用。

所以,至少调用ctl。用实数而不是anyInt,最好甚至替换所有anyInt()调用,因为它们实际上并没有改善这里的测试用例,而是实际上降低了测试的质量。

使用anyInt并不意味着测试证明任何int都可以工作。您需要知道要使用什么整数。例如,是否允许负整数?零?等等

编辑:因为它已在另一个答案中提出...是的,当然另一种可能性是“简化”错误消息,即它不需要实际的 ID。问题是:错误消息重要吗?里面的id重要吗?我猜是的,但这取决于用例。因此,如果确切的错误消息很重要,您将必须验证确切的错误消息 - 并在错误消息发生更改时调整您的测试。但这完全没问题,测试是为了确保特定的行为 - 如果确切的错误消息很重要,它是否是该特定行为的一部分并且必须进行测试。如果这种行为发生变化,单元测试的工作就是大喊“Boo-Hoo,该方法不再做它应该做的事情了。”。这就是单元测试的用途。如果特定的错误消息并不重要,但重要的是它包含 id,那么您可以对此进行验证(使用 containsArgumentCaptor)。如果仅重要的是调用错误方法,而不管实际消息如何,则验证 anyString() 并完成它。

关于java - 使用模拟验证错误消息,其中结果可以根据 id 更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33385997/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com