EasyMock的andReturn()与andStubReturn()的区别

56

andReturn(T value)andStubReturn(T value)在EasyMock中有什么区别?

在什么情况下,你会使用andStubReturn()而不是andReturn()来达到相同的结果?

2个回答

58
你在mock对象上使用存根返回值来表示你希望发生的方法调用,但其他情况下并不感兴趣。对于“普通”的方法调用,你使用常规返回。考虑以下方法:
public void someMethod(String arg) {
    if (logger.isDebugEnabled()) {
        logger.debug("Calling doSomething() on service " 
                       + service.getName().hashCode());
    }

    service.postMessage("{" + arg + "}");

    if (logger.isDebugEnabled()) {
        logger.info("Finished calling doSomething() on service " 
                      + service.getName().hashCode());
    }
}

...其中service是一个可模拟的字段。 日志语句中的hashCode()是人为构造的,但重点是您的模拟需要对任何调用getName()做出响应,以避免NPE,而您对它不关心。

当为此方法编写基于EasyMock的单元测试时,您将andStubReturn()调用getName()并使用普通的andReturn()调用postMessage(String)。当您验证模拟对象时,它只会考虑后者,如果更改log4j配置,则您的测试不会出错。


11
让我确认一下,基本上 andStubReturn() 用于我们在测试模拟对象时不关心的方法,但我们必须模拟返回值,否则代码将无法运行。andStubReturn() 方法不受 EasyMock 验证,而 andReturn() 方法要受到验证。 - Glide
嗨,使用andReturn()和额外的expectLastCall().anyTimes()是否相同? - Konstantin Milyutin
1
不,它们不同。[Anytimes] 使得该方法可以在模拟对象上被调用任意次数,但是所有这样的调用都将被验证。也就是说,如果任何一个调用没有使用模拟对象方法,则结果将失败。 - SnoopyMe
6
andStubReturn() 方法设置一个默认返回值,仅在常规的 .andReturn() 方法已被用完时作为后备返回值。EasyMock维护者提供的示例:http://tech.groups.yahoo.com/group/easymock/message/1069 - Stefan L

6

为了更清楚地说明,需要额外注意以下内容。

如果您使用 .andStubReturn()(或者使用 .andReturn(foo).anyTimes()),则不会有最小预期调用次数。因此,如果您使用这两个方法设置模拟期望,并且模拟的方法没有被调用,则 .verify() 调用将不会断言。

以下示例在未调用模拟方法时不会进行断言:

FooClass myFooClass = EasyMock.createNiceMock(FooClass.class);
EasyMock.expect(myFooClass.someMethod(EasyMock.anyInt()).andStubReturn(true);
EasyMock.replay(myFooClass);

EasyMock.verify(myFooClass);

当模拟的方法没有被调用时,将会断言的示例:

FooClass myFooClass = EasyMock.createNiceMock(FooClass.class);
EasyMock.expect(myFooClass.someMethod(EasyMock.anyInt()).andReturn(true).atLeastOnce();
EasyMock.replay(myFooClass);

EasyMock.verify(myFooClass);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接