JUnit Easymock 意外的方法调用
Posted
技术标签:
【中文标题】JUnit Easymock 意外的方法调用【英文标题】:JUnit Easymock Unexpected method call 【发布时间】:2011-01-08 00:01:09 【问题描述】:我正在尝试使用 EasyMock 在 JUnit 中设置测试,但遇到了一个小问题,我似乎无法解决这个问题。我希望这里有人可以提供帮助。
这是我正在尝试测试的方法的简化版本:
public void myMethod()
//(...)
Obj myObj = this.service.getObj(param);
if (myObj.getExtId() != null)
OtherObj otherObj = new OtherObj();
otherObj.setId(myObj.getExtId());
this.dao.insert(otherObj);
//(...)
好的,我使用 EasyMock 模拟了 service.getObj(myObj)
调用,效果很好。
当 JUnit 调用 dao.insert(otherObj
) 时,我的问题就出现了。 EasyMock 会在上面抛出一个*Unexpected Method Call*
。
我不介意在我的测试中嘲笑该 dao 并在其上使用 expectLastCall().once();
,但这假设我在插入时作为参数传递的“otherObj”上有句柄......
我当然不会,因为它是在被测试方法的上下文中有条件地创建的。
有没有人曾经处理过这个问题并以某种方式解决了它?
谢谢。
【问题讨论】:
【参考方案1】:您还可以使用EasyMock.isA(OtherObj.class)
来提高类型安全性。
【讨论】:
【参考方案2】:如果您无法在测试代码中获得对对象本身的引用,您可以使用EasyMock.anyObject()
作为insert
方法的预期参数。顾名思义,它会期望使用.. 任何对象调用该方法:)
它可能比匹配确切的论点不那么严格,但如果你对它感到满意,不妨试一试。请记住在声明预期的方法调用时包含对OtherObj
的强制转换。
【讨论】:
【参考方案3】:如果你只是想通过这个调用,anyObject() 匹配器非常有用,但如果你真的想验证构造的对象是你认为的那样,你可以使用 Capture。它看起来像:
Capture<OtherObj> capturedOtherObj = new Capture<OtherObj>();
mockDao.insert(capture(capturedOtherObj));
replay(mockDao);
objUnderTest.myMethod();
assertThat("captured what you expected", capturedOtherObj.getValue().getId(),
equalTo(expectedId));
此外,PowerMock 可以预期构造一个对象,因此如果需要,您可以查看它。
【讨论】:
【参考方案4】:另请注意,如果您使用EasyMock.createStrictMock();
,则方法调用的顺序也很重要,如果您违反此规则,则会引发意外的方法调用。
【讨论】:
以上是关于JUnit Easymock 意外的方法调用的主要内容,如果未能解决你的问题,请参考以下文章