在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
不存在 - 它们就是我要求的。
或者我需要自己实现这个吗?
答案 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匹配器应该能够充分测试相关对象。希望这会有所帮助。