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

Arn*_*tta 5 java regex tdd bdd mockito

描述

我正在尝试测试以下类:

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");
     }
   }

 }
Run Code Online (Sandbox Code Playgroud)

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

  • 捕获提供给日志对象的参数(我在我的测试atm中嘲笑)
  • 检查(使用正则表达式)是否与我的模拟候选对象返回的情况匹配"候选人#\ d +:不同步"之类的模式

测试代码

以下代码是我的起点:

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")
  ???
}
Run Code Online (Sandbox Code Playgroud)

问题

问题是log.debug被多次调用.我想捕获提供给log.debug它的参数,并确保在使用对同步无效的候选项调用时,记录器对象会正确记录候选者未同步的情况.

编辑:如果之前有人问过,我道歉.我恳请您发布相关问题的链接:)

小智 9

Mockito在标准的org.mockito.Matchers类中提供正则表达式匹配器.以下是如何使用此函数验证具有适当参数值的调用的示例:

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


fge*_*fge 2

You can use this:

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());
Run Code Online (Sandbox Code Playgroud)

(note: this code assumes that the Logger's .debug() method returns void; I don't know of any Logger which does not, but who knows)

  • 我想补充一点,您使用 ArgumentCaptor 的原始答案也没有错误。我使用“ArgumentCaptor.getAllValues()”来提取所有日志消息:) (2认同)