Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Standard way to capture arguments in JMock

Is there an already built-in, standard way in JMock to capture method arguments to test the argument object later on with standard JUnit functionality?

Something like

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

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

CapturedContainer and captureTo do not exist — they are what I'm asking for.

Or do I need to implement this on my own?

like image 469
Ralph Avatar asked Jun 17 '11 12:06

Ralph


2 Answers

You can do this by implementing a new Matcher that captures the argument when match is called. This can be retrieved later.

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

Then you can use this when setting up your expectations.

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();
like image 138
Mark H Avatar answered Oct 14 '22 16:10

Mark H


I think you're missing the point a little here. The idea is to specify in the expectation what should happen, rather than capturing it and checking later. That would look like:

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

or perhaps, for a looser condition,

context.checking(new Expectations() {{
    oneOf(emailService.getJavaMailSender()).send(with(startsWith("hello world")));
}});
like image 45
Steve Freeman Avatar answered Oct 14 '22 14:10

Steve Freeman