Стандартный способ захвата аргументов в JMock - PullRequest
8 голосов
/ 17 июня 2011

Существует ли в JMock уже встроенный стандартный способ сбора аргументов метода для проверки объекта аргумента в дальнейшем со стандартной функциональностью JUnit?

Что-то вроде

final CapturedContainer<SimpleMailMessage>capturedArgumentContainer = new ...
context.checking(new Expectations() {{
    oneOf(emailService.getJavaMailSender()).send(
       with(captureTo(capturedArgumentContainer)));
}});

assertEquals("helloWorld", capturedArgumentContainer.getItem().getBody());

CapturedContainer и captureTo не существуют - это то, что я прошу.

Или мне нужно реализовать это самостоятельно?

Ответы [ 3 ]

10 голосов
/ 02 декабря 2011

Вы можете сделать это, реализовав новый Matcher, который захватывает аргумент при вызове match.Это можно получить позже.

class CapturingMatcher<T> extends BaseMatcher<T> {

  private final Matcher<T> baseMatcher;

  private Object capturedArg;

  public CapturingMatcher(Matcher<T> baseMatcher){
    this.baseMatcher = baseMatcher;
  }

  public Object getCapturedArgument(){
    return capturedArg;
  }

  public boolean matches(Object arg){
    capturedArg = arg;
    return baseMatcher.matches(arg);
  }

  public void describeTo(Description arg){
    baseMatcher.describeTo(arg);
  }
}

Затем вы можете использовать это при настройке ваших ожиданий.

final CapturingMatcher<ComplexObject> captureMatcher 
  = new CapturingMatcher<ComplexObject>(Expectations.any(ComplexObject.class));

mockery.checking(new Expectations() {{
      one(complexObjectUser).registerComplexity(with(captureMatcher));
}});

service.setComplexUser(complexObjectUser);

ComplexObject co = 
  (ComplexObject)captureMatcher.getCapturedArgument();

co.goGo();
5 голосов
/ 25 июня 2011

Я думаю, вы здесь немного упускаете из виду.Идея состоит в том, чтобы указать в ожидании , что должно произойти, а не захватывать его и проверять позже.Это будет выглядеть так:

context.checking(new Expectations() {{
    oneOf(emailService.getJavaMailSender()).send("hello world");
}});

или, возможно, для более свободного состояния,

context.checking(new Expectations() {{
    oneOf(emailService.getJavaMailSender()).send(with(startsWith("hello world")));
}});
0 голосов
/ 15 марта 2016

Я оказался в подобной ситуации, желая проверить поле объекта, переданного в макет. Вместо того, чтобы использовать сопоставление захвата, как показывает Марк, я попробовал то, что считаю более подходящим для JMock. Код с учетом вашего варианта использования:

mockery.checking(new Expectations() {{
  oneOf(emailService.getJavaMailSender()).send(
    with(Matchers.<SimpleMailMessage>hasProperty("body", equal("Hello world!"))));
}});

Я понимаю, что у этого есть ограничения, но в большинстве случаев сопоставители с подколенным сухожилием должны быть способны протестировать рассматриваемый объект достаточно. Надеюсь, это поможет.

...