【问题标题】:Mockito verify argument contains another string ignoring caseMockito 验证参数包含另一个忽略大小写的字符串
【发布时间】:2023-04-10 09:23:01
【问题描述】:

我得到的是这一行:

verify( mockAppendable ).append( org.mockito.Mockito.contains( msg ) );

...但我希望这个测试不区分大小写。我该怎么做?

【问题讨论】:

标签: java mocking mockito verify


【解决方案1】:

the page 上,“您可以提取方法”是什么意思,是否可以使用 Java 8 lambda 来使其成为单线?

在一行中使用来自here 的不区分大小写的代码:

verify(mockAppendable)
    .append(
       argThat(arg ->
         Pattern.compile(Pattern.quote(msg), Pattern.CASE_INSENSITIVE).matcher(arg).find()));

所以他们通过跳过指定自定义错误消息来允许 lambda 版本。

“你可以提取一个方法”,他们的意思是:

verify(mockAppendable).append(argThat(containsCaseInsensitive(msg)));

并且方法定义为:

public static ArgumentMatcher<String> containsCaseInsensitive(final string s) {
    if (s == null) throw new IllegalArgumentException("s is null");
    final Pattern pattern = Pattern.compile(Pattern.quote(s), Pattern.CASE_INSENSITIVE);
    return new ArgumentMatcher<String>() {

        @Override
        public boolean matches(String arg) {
            return arg != null && pattern.matcher(arg).find();
        }

        @Override 
        public String toString() {
            return String.format("[should have contained, ignoring case, \"%s\"]", s);
        }
    };
}

这是完全可重用的,您可以将其放在像 MocitoMatchers 这样的新类中,并像任何内置匹配器一样从许多测试中调用。

【讨论】:

  • 太棒了。非常感谢!
  • 您愿意看看我的“containsCaseInsensitive”版本吗?并可能编辑你的? (考虑到空参数和更好的可读性)...我尝试提交编辑,但我搞砸了,第三方审阅者拒绝了它...
  • 您的可能更完整,但 SO 不是在这里提供可复制和可粘贴的库质量代码。所有空检查和不同的消息只是人们可以选择添加的噪音,如果他们愿意并且不会对问题产生影响。
  • 再三考虑,如果出现null argument,最好返回false,并且还不如检查输入。
  • 我使用s 作为字符串,因为这是String::contains 中的参数名称。该消息实际上是个人喜好,但我会使用您的。
【解决方案2】:

感谢 JB Nizet,我发现答案似乎是这样的课程:

class ContainsThisIgnoringCase implements ArgumentMatcher<String> {
    private String msg;
    ContainsThisIgnoringCase( String msg ){
        this.msg = msg;
    }
    @Override
    public boolean matches(String arg ) {
        return arg.toLowerCase().contains( msg.toLowerCase() );
    }
    @Override 
    public String toString(){
        return msg;
    }
}

但是,我对我在the page 上看到的他的链接指向的内容感到困惑:
a) “你可以提取方法”是什么意思,
b) 是否有可能使用 Java 8 lambda 使其成为单线?

【讨论】:

    【解决方案3】:

    page 上,“您可以提取方法”是什么意思,是否可以 使用 Java 8 lambda 使其成为单线?

    这只是意味着不必将new ListOfTwoElements() 放入您的测试代码中,您可以向您的测试类添加一个名为listOfTwoElements() 的方法,该方法返回一个新的ListOfTwoElements 对象以使测试代码更加流畅。

    要回答有关使其成为单行的问题,更重要的是,要回答此帖子的原始问题,您可以使用核心 Mockito 库中的 MockitoHamcrest 和 Hamcrest 库中的 IsEqualIgnoringCase 来获得一个班轮不需要自定义类或 lambda:

    import static org.hamcrest.text.IsEqualIgnoringCase.equalToIgnoringCase;
    import static org.mockito.Mockito.when;
    import static org.mockito.hamcrest.MockitoHamcrest.argThat;
    
    class CookieUtilTest {
    
        @Mock
        private HttpServletResponse response;
    
        @Test
        public void testHasCookiesDoesNotMatchCaseSensitiveCookieName() {
            when(response.getHeaders(argThat(equalToIgnoringCase("Set-Cookie")))).thenReturn(singletonList("CookieNames=AreCaseSensitive"));
    
            boolean testValue = CookieUtil.hasCookie("cookieNames", response);
    
            verify(response).getHeaders(argThat(equalToIgnoringCase("Set-Cookie")));
            assertThat(testValue).isFalse();
        }
    }
    

    【讨论】:

      【解决方案4】:

      到目前为止,无需编写额外匹配器的最简单方法是使用 matches(String regex) 帮助器。只需将嵌入的 case insensitive 标志与您的字符串一起使用,您就可以开始了:

      verify( mockAppendable ).append( matches("(?i)the-message") );
      

      【讨论】:

        猜你喜欢
        • 2012-12-10
        • 1970-01-01
        • 2015-07-18
        • 2013-05-12
        • 1970-01-01
        • 2021-11-05
        • 2020-05-07
        • 2016-01-29
        • 2013-05-24
        相关资源
        最近更新 更多