1. 概述

在这篇教程中,我们将探讨如何测试我们的代码是否调用了一个lambda函数。实现这个目标有两种方法。首先,我们会检查lambda是否被传入了正确的参数。然后,我们将关注测试其行为,确认lambda代码是否执行并产生了预期的结果。

2. 需要测试的示例类

首先,创建一个名为LambdaExample的类,其中包含一个名为bricksListArrayList

class LambdaExample {
    ArrayList<String> bricksList = new ArrayList<>();
}

接下来,添加一个名为BrickLayer的内部类,它能为我们添加砖块:

class LambdaExample {

    BrickLayer brickLayer = new BrickLayer();

    class BrickLayer {
        void layBricks(String bricks) {
            bricksList.add(bricks);
        }
    }
}

BrickLayer的功能很简单,只有一个名为layBricks()的方法,用于将砖块添加到我们的列表中。这原本可以是外部类,但为了保持概念简洁,这里使用内部类。

最后,在LambdaExample中添加一个方法,通过lambda调用layBricks()

void createWall(String bricks) {
    Runnable build = () -> brickLayer.layBricks(bricks);
    build.run();
}

我们保持了简单。在实际应用中,情况会更复杂,但这个精简的例子有助于解释测试方法。

在接下来的部分,我们将测试createWall()调用是否导致lambda中预期的layBricks()方法执行。

3. 测试正确调用

我们将首先介绍的测试方法是基于确认lambda在我们期望的时间被调用,并且接收到正确的参数。首先,我们需要为BrickLayerLambdaExample创建模拟对象:

@Mock
BrickLayer brickLayer;
@InjectMocks
LambdaExample lambdaExample;

我们在LambdaExample上应用了@InjectMocks注解,使其使用模拟的BrickLayer对象。这样,我们就能确认对layBricks()方法的调用了。

现在我们可以编写测试:

@Test
void whenCallingALambda_thenTheInvocationCanBeConfirmedWithCorrectArguments() {
    String bricks = "red bricks";
    lambdaExample.createWall(bricks);
    verify(brickLayer).layBricks(bricks);
}

在这个测试中,我们定义了要添加到bricksListString,并通过createWall()方法传递给它。请注意,我们使用了先前创建的模拟对象作为LambdaExample的实例。

然后,我们使用Mockito的verify()函数。***verify()在这个类型的测试中非常有用,它确认layBricks()方法已被调用,并且传入了我们期望的参数。**

verify()功能远不止于此。例如,确认某个方法被调用了多少次。然而,对于我们的目的,确认lambda按预期调用方法就足够了。

4. 测试正确行为

另一种测试途径是不关心何时以及如何被调用,而是确认lambda函数的预期行为是否发生。通常,我们调用函数总有其合理的原因,可能是进行计算或获取或设置变量。

在我们的例子中,lambda将给定的String添加到ArrayList中。在这个部分,让我们验证lambda成功执行了这个任务:

@Test
void whenCallingALambda_thenCorrectBehaviourIsPerformed() {
    LambdaExample lambdaExample = new LambdaExample();
    String bricks = "red bricks";
        
    lambdaExample.createWall(bricks);
    ArrayList<String> bricksList = lambdaExample.getBricksList();
        
    assertEquals(bricks, bricksList.get(0));
}

我们创建了一个LambdaExample类的实例,然后调用createWall()将砖块添加到ArrayList中。

现在我们应该看到bricksList包含了我们刚添加的String。假设代码正确执行了lambda,我们通过从lambdaExample中获取bricksList并检查内容来确认这一点。

我们可以得出结论,lambda按照预期执行,因为这是唯一能使我们的String出现在ArrayList中的方式。

5. 总结

在这篇文章中,我们探讨了测试lambda调用的两种方法。当我们可以模拟包含函数的类并将其注入到以lambda形式调用它的类时,第一种方法很有用。在这种情况下,我们可以使用Mockito来验证对函数的调用和传入的正确参数。然而,这并不能保证lambda后续的行为。

另一种选择是测试lambda在被调用时产生预期结果。这种方法提供了更多的测试覆盖率,如果确认函数调用的正确行为相对简单,通常更可取。

如往常一样,所有示例的完整代码可以在GitHub上找到。