如何使用Mockito模拟接受lambda的方法,以便能够控制将哪些参数传递给回调?我专门尝试模拟这样使用的JDBI method useExtension
:
jdbi.useExtension(OrgUnitDao.class, dao -> {
// Skip if already loaded
// Skip if already loaded
if (dao.orgUnitsAreLoaded()) {
我想替换传递回回调的dao
对象,以便可以使用dao.orgUnitsAreLoaded()
的返回值控制分支。
签名看起来像这样
public <E,X extends Exception> void useExtension(Class<E> extensionType,
ExtensionConsumer<E,X> callback)
throws NoSuchExtensionException,
X extends Exception
答案 0 :(得分:0)
这是我问题的完整答案。它已简化为如何进行存根的最基础知识,因此也无法反映我要测试的生产代码,但它恰好显示了执行此操作所需的机制。
final Jdbi jdbi = mock(Jdbi.class);
doAnswer(invocation -> {
System.out.println("this is the doAnswer lambda - just setting up the answer and the mocks");
final Class<OrgUnitDao> daoClass = invocation.getArgument(0);
final ExtensionConsumer callback = invocation.getArgument(1);
final OrgUnitDao mock1 = mock(daoClass);
when(mock1.orgUnitsAreLoaded()).thenReturn(false);
// call the actual callback method
callback.useExtension(mock1);
return null;
}).when(jdbi).useExtension(eq(OrgUnitDao.class), any());
// This is the method call I am to test
// Regard this as hidden away in some outer method in
// the System-Under-Test, but that I have been able
// to inject all its dependencies
jdbi.useExtension(OrgUnitDao.class, new Foo());
/// Further down, outside of the method
// Only replaced the lambda with this to get toString() for debugging ...
class Foo implements ExtensionConsumer<OrgUnitDao, RuntimeException> {
@Override
public void useExtension(OrgUnitDao orgUnitDao) throws RuntimeException {
System.out.println("A real method call, now using the passed in mocked dao:" + orgUnitDao.orgUnitsAreLoaded());
}
@Override
public String toString() {
return "OrgUnitDao class";
}
}
答案 1 :(得分:0)
为使问题"Calling callbacks with Mockito"上的对话并行进行,您的lambda可能在被测方法的执行期间被同步调用,或者稍后可能由于某些外部因素或交互而被调用。像Dawood's answer there一样,your answer here也可以使用Mockito答案,并且是寻找同步样式的唯一方法(mockJdbi
在{{1}之前立即调用lambda }返回)。如果您要异步调用lambda,或者您的系统允许您异步调用lambda,则可能要在被测方法返回后测试状态,但在交互之前请测试与lambda 。
methodUnderTest
尽管lambda减少了以前与匿名内部类相关联的样板,但您也可能更喜欢使用Captor样式,因为它可以避免创建冗长的Answer实现并在其中隐藏测试断言或Mockito验证。如果您的项目偏向于具有清晰的“先给定时”结构的BDD风格的模拟程序,这尤其诱人(尽管我的示例更类似于“先给定时后给定”)。