使用Mockito验证lambda的方法

问题描述 投票:0回答:1

我正试图以此来验证和捕获lambda表达式内某些方法调用的参数:

public Optional<UserDetails> findOne(String userName) {
    String selectStatement =
        "SELECT * FROM users WHERE userName = :userName;";

    return jdbi.withHandle(handle -> handle
            .createQuery(selectStatement)
            .bind("userName", userName)
            .map(new UserDetailsMapper())
            .findOne());
  }

[jdbi.withHandle()接受参数HandleCallBack,看起来像这样:

public interface HandleCallback<T, X extends Exception> {
  T withHandle(Handle handle) throws X;
}

例如,我想验证是否已使用.bind()调用了"userName"并从我的userName方法中传入了findOne自变量字符串。

感觉好像我在对Jdbi类而不是我自己的类进行单元测试,但是我觉得.createQuery() .bind().map()的参数应该进行测试,因为开发人员可能会意外更改它们。

我目前采用的方法是创建一个内存数据库并测试实际返回的内容,但这感觉更像是集成测试而不是单元测试。我也不太在乎Jdbi .withHandle()方法实际上返回的内容,因为那时我实际上将在测试一个库。

我的理解是,我应该对传递给.withHandle()的参数(在本例中为lambda表达式)进行单元测试,这是我在这里要做的。

我最接近的是通过将逻辑移到方法引用中,但是当userName传递到我的findOne()方法中然后在lambda中使用时,该方法不起作用。

我也玩过Mockito的doAnswer,但无济于事。

[我只能考虑使用辅助方法创建一个新类来返回userNameselectStatement等,并验证它们是否被调用,但是感觉上没有必要,将其添加只是为了提供可测试性。

java unit-testing lambda junit mockito
1个回答
0
投票
lambda表达式是findOne方法的实现的一部分。因此,您应该在测试findOne的过程中对其进行测试。但是在执行对findOne的调用时不会执行它。因此,要能够对其进行测试,执行findOne并对其进行验证和断言是不够的。

我会模拟jdbi,然后使用捕获lambda函数的ArgumentCaptor对调用进行验证。然后,您可以将该lambda函数作为参数传递给测试该lambda函数的测试方法。该方法可以与任何其他测试方法相同,只是它永远不能作为单独的测试用例运行。

在这种情况下,我认为一种这样的测试方法就足够了。但是有时在测试lambda函数时,您可能需要创建并调用多种测试方法,以使用不同的输入值测试捕获的lambda函数。

© www.soinside.com 2019 - 2024. All rights reserved.