easymock - 匹配器和多次调用

发布于 2024-08-06 10:04:33 字数 2831 浏览 2 评论 0原文

下面是我完成的一个使用它自己的匹配器的测试。我知道在这种情况下我可以使用标准匹配器,但在我的真实代码中我需要一个更复杂的匹配器。

测试通过 - 勾选 VG。 问题在于,似乎对 IArgumentMatcher.matches() 方法进行了额外调用,该方法返回 false,但测试通过了。

我得到的输出是:

30-09-2009 16:12:23 [main] ERROR - MATCH - expected[aa], actual[aa]
30-09-2009 16:12:23 [main] ERROR - MISMATCH - expected[aa], actual[bb]
30-09-2009 16:12:23 [main] ERROR - MATCH - expected[bb], actual[bb]

所以问题是为什么我会得到 MISMATCH 行, 我做错了什么吗?

测试代码为:

package uk.co.foo;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import junit.framework.TestCase;

import org.apache.log4j.Logger;
import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;

/**
 *
 */
public class BillTest extends TestCase { 

  private static Logger mLogger = Logger.getLogger(BillTest.class);

  private BillInterface mMockBill;

  public void testTwoCalls() throws Exception {
    BillsTestClass sut = new BillsTestClass();
    sut.setDao(mMockBill);

    expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn("");
    expect(mMockBill.method1(eqBillMatcher("bb"))).andReturn("");
    replay(mMockBill);

    //test method
    sut.doSomething("aa");
    sut.doSomething("bb");

    verify(mMockBill);
  }

  public String eqBillMatcher(String aIn) {
    EasyMock.reportMatcher(new BillMatcher(aIn));
    return null;
  }

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    mMockBill = createMock(BillInterface.class);
  }


  @Override
  protected void tearDown() throws Exception {
    super.tearDown();
    reset(mMockBill);
  }

  public class BillsTestClass {
    private BillInterface mDao;
    public void setDao(BillInterface aDao) {
      mDao = aDao;
    }

    public void doSomething(String aValue) {
      mDao.method1(aValue);
    }
  }

  public interface BillInterface {
    String method1(String aValue);
  }

  public class BillMatcher implements IArgumentMatcher {
    private String mExpected;

    public BillMatcher(String aExpected) {
      mExpected = aExpected;
    }

    /**
    * @see org.easymock.IArgumentMatcher#matches(java.lang.Object)
    *  {@inheritDoc}
    */
   public boolean matches(Object aActual) {
     if (aActual.equals(mExpected)) {
       mLogger.error("MATCH - expected[" + mExpected + "], actual[" + aActual + "]");
       return true;
     }
     mLogger.error("MISMATCH - expected[" + mExpected + "], actual[" + aActual + "]");
     return false;
   }

   /**
    * @see org.easymock.IArgumentMatcher#appendTo(java.lang.StringBuffer)
    *  {@inheritDoc}
    */
   public void appendTo(StringBuffer aBuffer) {
     aBuffer.append("boo(");
   }
  }
}

Below is a test I have knocked up that uses its own matcher. I know in this case I could use a standard matcher but in my real code I need a more complicated one.

The test passes - tick VG.
The issue is that there appears to be an extra call to IArgumentMatcher.matches() method that returns false, and yet the test passes.

The output I get is:

30-09-2009 16:12:23 [main] ERROR - MATCH - expected[aa], actual[aa]
30-09-2009 16:12:23 [main] ERROR - MISMATCH - expected[aa], actual[bb]
30-09-2009 16:12:23 [main] ERROR - MATCH - expected[bb], actual[bb]

So the question is why am I getting the MISMATCH line,
and have I done something incorrectly?

The test code is:

package uk.co.foo;

import static org.easymock.EasyMock.createMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.reset;
import static org.easymock.EasyMock.verify;
import junit.framework.TestCase;

import org.apache.log4j.Logger;
import org.easymock.EasyMock;
import org.easymock.IArgumentMatcher;

/**
 *
 */
public class BillTest extends TestCase { 

  private static Logger mLogger = Logger.getLogger(BillTest.class);

  private BillInterface mMockBill;

  public void testTwoCalls() throws Exception {
    BillsTestClass sut = new BillsTestClass();
    sut.setDao(mMockBill);

    expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn("");
    expect(mMockBill.method1(eqBillMatcher("bb"))).andReturn("");
    replay(mMockBill);

    //test method
    sut.doSomething("aa");
    sut.doSomething("bb");

    verify(mMockBill);
  }

  public String eqBillMatcher(String aIn) {
    EasyMock.reportMatcher(new BillMatcher(aIn));
    return null;
  }

  @Override
  protected void setUp() throws Exception {
    super.setUp();
    mMockBill = createMock(BillInterface.class);
  }


  @Override
  protected void tearDown() throws Exception {
    super.tearDown();
    reset(mMockBill);
  }

  public class BillsTestClass {
    private BillInterface mDao;
    public void setDao(BillInterface aDao) {
      mDao = aDao;
    }

    public void doSomething(String aValue) {
      mDao.method1(aValue);
    }
  }

  public interface BillInterface {
    String method1(String aValue);
  }

  public class BillMatcher implements IArgumentMatcher {
    private String mExpected;

    public BillMatcher(String aExpected) {
      mExpected = aExpected;
    }

    /**
    * @see org.easymock.IArgumentMatcher#matches(java.lang.Object)
    *  {@inheritDoc}
    */
   public boolean matches(Object aActual) {
     if (aActual.equals(mExpected)) {
       mLogger.error("MATCH - expected[" + mExpected + "], actual[" + aActual + "]");
       return true;
     }
     mLogger.error("MISMATCH - expected[" + mExpected + "], actual[" + aActual + "]");
     return false;
   }

   /**
    * @see org.easymock.IArgumentMatcher#appendTo(java.lang.StringBuffer)
    *  {@inheritDoc}
    */
   public void appendTo(StringBuffer aBuffer) {
     aBuffer.append("boo(");
   }
  }
}

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

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

发布评论

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

评论(1

青衫负雪 2024-08-13 10:04:33

快速播放,看起来您没有定义顺序,只是应该期待一些事情。每次调用模拟时,它都会按顺序遍历每个期望,直到找到匹配且之前未调用过的期望。

所以:

expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn("");
expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn("");
expect(mMockBill.method1(eqBillMatcher("cc"))).andReturn("");

sut.doSomething("aa");

匹配 - 预期[aa],实际[aa]

正如您所期望的。首场比赛命中。

sut.doSomething("cc");

不匹配 - 预期[aa],实际[cc]
不匹配 - 预期 [aa],实际 [cc]
匹配 - 预期[cc],实际[cc]

按顺序排列每个(包括已经通过的),直到找到匹配项。

sut.doSomething("aa");

匹配 - 预期[aa],实际[aa]
匹配 - 预期[aa],实际[aa]

每个按顺序排列,直到找到之前未调用过的命中。

这将使其能够在“意外的方法调用,预期 1,实际 1 (+1)”行上提供错误消息。

--

注释代码 -

private boolean used = false;

<snip/>

public boolean matches(Object aActual) {
   if (used) {
     return false;
   }
   used = true;

A quick play and it looks like you do not define order just that something should be expected. Each time you make a call to the mock it runs through every expectation in order until it finds one that matches and has not been called before.

So with:

expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn("");
expect(mMockBill.method1(eqBillMatcher("aa"))).andReturn("");
expect(mMockBill.method1(eqBillMatcher("cc"))).andReturn("");

sut.doSomething("aa");

MATCH - expected[aa], actual[aa]

Just as you would expect. First match hits.

sut.doSomething("cc");

MISMATCH - expected[aa], actual[cc]
MISMATCH - expected[aa], actual[cc]
MATCH - expected[cc], actual[cc]

Each one in order (including ones that have already passed) until it finds a hit.

sut.doSomething("aa");

MATCH - expected[aa], actual[aa]
MATCH - expected[aa], actual[aa]

Each in order until it finds a hit that has not been called before.

This would enable it to provide the error messages on the lines of "unexpected method call, expected 1, actual 1 (+1).

--

Code for comment -

private boolean used = false;

<snip/>

public boolean matches(Object aActual) {
   if (used) {
     return false;
   }
   used = true;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文