用于链接调用的模拟或存根

2022-08-31 11:00:12
protected int parseExpire(CacheContext ctx) throws AttributeDefineException {
    Method targetMethod = ctx.getTargetMethod();
    CacheEnable cacheEnable = targetMethod.getAnnotation(CacheEnable.class);
    ExpireExpr cacheExpire = targetMethod.getAnnotation(ExpireExpr.class);
    // check for duplicate setting
    if (cacheEnable.expire() != CacheAttribute.DO_NOT_EXPIRE && cacheExpire != null) {
        throw new AttributeDefineException("expire are defined both in @CacheEnable and @ExpireExpr");
    }
    // expire time defined in @CacheEnable or @ExpireExpr
    return cacheEnable.expire() != CacheAttribute.DO_NOT_EXPIRE ? cacheEnable.expire() : parseExpireExpr(cacheExpire, ctx.getArgument());
}

这是测试的方法,

Method targetMethod = ctx.getTargetMethod();
CacheEnable cacheEnable = targetMethod.getAnnotation(CacheEnable.class);

我必须模拟三个CacheContext,Method和CacheEnable。有没有让测试用例更简单的想法?


答案 1

Mockito可以处理链接的存根

Foo mock = mock(Foo.class, RETURNS_DEEP_STUBS);

// note that we're stubbing a chain of methods here: getBar().getName()
when(mock.getBar().getName()).thenReturn("deep");

// note that we're chaining method calls: getBar().getName()
assertEquals("deep", mock.getBar().getName());

AFAIK,链中的第一个方法返回一个 mock,该 mock 设置为在第二个链式方法调用时返回您的值。

Mockito的作者指出,这应该只用于遗留代码。否则,更好的做法是将行为推送到 CacheContext 中,并提供完成工作本身所需的任何信息。您从 CacheContext 中提取的信息量表明您的类具有功能嫉妒


答案 2

以防万一你正在使用Kotlin。MockK没有说链接是一种不好的做法,并且很容易让你这样做

val car = mockk<Car>()

every { car.door(DoorType.FRONT_LEFT).windowState() } returns WindowState.UP

car.door(DoorType.FRONT_LEFT) // returns chained mock for Door
car.door(DoorType.FRONT_LEFT).windowState() // returns WindowState.UP

verify { car.door(DoorType.FRONT_LEFT).windowState() }

confirmVerified(car)

推荐