在JMock中捕获参数的标准方法

时间:2011-06-17 12:39:52

标签: java testing junit jmock

在JMock中是否有已内置的标准方法来捕获方法参数,以便稍后使用标准JUnit功能测试参数对象?

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

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

CapturedContainercaptureTo不存在 - 它们就是我要求的。

或者我需要自己实现这个吗?

3 个答案:

答案 0 :(得分:10)

您可以通过实现一个新的匹配器来执行此操作,该匹配器在调用匹配时捕获参数。这可以在以后检索。

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

答案 1 :(得分:5)

我认为你在这里忽略了一点。我们的想法是在期望中指定 应该发生什么,而不是捕获它并在以后检查。那看起来像是:

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

或者,对于更宽松的条件,

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

答案 2 :(得分:0)

我发现自己处于类似的情况,想要检查传递给模拟器的对象的字段。而不是像马克所说的那样使用捕获匹配器,而是尝试了我认为更多JMock做事方式。根据您的使用情况调整代码:

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

我知道这有局限性,但在大多数情况下,hamcrest匹配器应该能够充分测试相关对象。希望这会有所帮助。