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

发布于 2024-11-16 01:56:39 字数 534 浏览 5 评论 0原文

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

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

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

CapturedContainercaptureTo 这样的东西不存在 - 它们就是我所要求的。

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

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

千纸鹤 2024-11-23 01:56:39

您可以通过实现一个新的 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();

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();
生寂 2024-11-23 01:56:39

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

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

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

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

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")));
}});
素食主义者 2024-11-23 01:56:39

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

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

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

I found myself in a similar situation wanting to check a field of an object passed into a mock. Instead of using a capturing matcher as Mark illustrates I tried what I consider the more JMock way of doing things. Code adjusted for your use case:

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

I understand that this has limitations but hamcrest matchers should be able to test the object in question sufficiently in most cases. Hope this helps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文