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

Ral*_*lph 8 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());
Run Code Online (Sandbox Code Playgroud)

CapturedContainer并且captureTo不存在 - 它们就是我要求的.

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

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

然后,您可以在设定期望时使用此功能.

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


Ste*_*man 5

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

context.checking(new Expectations() {{
    oneOf(emailService.getJavaMailSender()).send("hello world");
}});
Run Code Online (Sandbox Code Playgroud)

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

context.checking(new Expectations() {{
    oneOf(emailService.getJavaMailSender()).send(with(startsWith("hello world")));
}});
Run Code Online (Sandbox Code Playgroud)

  • 你是对的.但有时使用起来很复杂(并且产生非常难以理解的代码).例如,在我的例子中:参数是一个复杂的对象,我只需要检查一个属性(正文).所以代码将成为一个群众. (3认同)
  • 我不同意:如果您的测试方法创建了一个对象,在两个调用中使用它并返回它,您可能想要检查两个调用中使用的对象和返回的对象是否都是同一个对象.为此,我没有看到另一种方法,而是能够捕获对象. (3认同)
  • 这是真的,但让我对设计感到好奇.一个具体的例子现在真的很方便...... (2认同)