Mockito 使用正则表达式验证是否使用正确的参数调用了方法

Mockito verify that method is called with correct argument using regex

描述

我正在尝试测试以下 class:

Class UserSynchronizer(){
   private static org.apache.log4j.Logger log = ... ;

   public Sync(candidate) { 
     ...
     if (candidate.inValidForSync()) {
       log.debug("Candidate #" + candidate.getId() + ": Not syncing");
     }
     else {
       log.debug("Syncing");
     }
   }

 }

我想看看 mockito 是否可以检测调用 log.debug 时使用的参数,然后我想看看我是否可以对其进行某种正则表达式检查。换句话说,我想:

测试代码

下面的代码是我的起点:

public void verifySyncDoesntSyncWhenInvalid(){
  //Setup candidate mock
  Candidate invalidSyncCandidateMock = mock(Candidate.class);
  when(invalidSyncCandidateMock.inValidForSync()).thenReturn(true);

  //Setup log mock
  UserSynchronizer userSynchronizer = ...;
  Field logField = userSynchronizer.getClass().getDeclaredField("log");
  logField.setAccessible(true);
  logField.set(userSynchronizer, logMock);

  //Call sync
  userSynchronizer.sync(invalidSyncCandidateMock);

  //Verify that debug was called with ("Candidate #\d+: Not syncing")
  ???
}

问题

问题是 log.debug 被调用了多次。我想捕获提供给 log.debug 的参数,并确保当它与对同步无效的候选人一起调用时,记录器对象会正确记录候选人未同步。

编辑:如果之前有人问过这个问题,我深表歉意。恳请您 post 回答相关问题 link :)

你可以使用这个:

final List<String> messages = new ArrayList<>();

final Answer<Void> catchMeAll = new Answer<Void>()
{
    @Override
    public Void answer(final InvocationOnMock invocation)
    {
        messages.add((String) invocation.getArguments()[0]);
    }
}

doAnswer(catchMeAll).when(logMock).debug(anyString());

(注意:此代码假定 Logger.debug() 方法 returns void;我不知道任何 Logger没有,但谁知道)

另一种匹配方法是使用支持正则表达式的 Hamcrest 匹配器:

verify(logMock).debug(argThat(matchesPattern("Candidate #\d+: Not syncing")));

请注意,您必须自己编写,或使用尚未包含的 PatternMatcher or hamcrest-text-patterns as in JavaHamcrest issue #2

Mockito 在标准 org.mockito.Matchers class 中提供正则表达式匹配器。下面是一个示例,说明如何使用此函数来验证具有正确参数值的调用:

verify(restMock, times(1)).exchange(matches(".*text=welcome.*to.*blah"), eq(HttpMethod.GET), any(ResponseEntity.class), eq(String.class));