java - 测试依赖项调用的 lambda 表达式

标签 java unit-testing lambda junit java-8

我正在尝试测试 lambda 表达式中的一些代码,它是另一个类的回调。

class EmailSender {
    private EmailBuilder emailBuilder;

    public void send() {
        String testEmail = emailBuilder.buildEmail("Test Email", bodyContentAppender());
        //send testEmail
    }

    private Consumer<Email> bodyContentAppender() {
        //how to test this through JUnit?
        return email -> email.appendBody("Body Content");
    }
}

interface EmailBuilder {

    String buildEmail(String templateName, Consumer<Email> contentAppender);
}

getBodyContent 方法中的 lambda 表达式是从 EmailBuilder 调用的,它是 EmailSender 的 JUnit 测试中的模拟依赖项。由于我正在模拟 EmailBuilder 的行为,所以 getBodyContent 中的代码不会从测试中调用。如何测试这样的一 block ?

编辑: 在这种情况下,通过 Argument Captors 捕获 lambda 表达式不是解决方案,因为 EmailBuilder 的行为是模拟的,实际方法未被调用。其次,email.appendBody 对由外部 API 传递的对象进行一些转换,但创建起来并不简单。

最佳答案

您在这里要做的主要是验证工厂方法实际上确实返回了正确的对象。有 this related question ,其中共识是除了验证它确实返回正确类型的对象之外,不测试工厂方法的结果。该对象的行为应该在该类型的单元测试中进行测试。

在对 this related question on unit testing lambdas 的回答中斯图尔特·马克斯 (Stuart Marks) 认为

If the code in the lambda is complex enough that it warrants testing, maybe that code ought to be refactored out of the lambda, so that it can be tested using the usual techniques.

现在,真正的问题是:如果这不是一个 lambda,而是一个具体的类 MyBodyContentAppender实现功能接口(interface)Consumer<Email> ,你会如何对它进行单元测试?你会为这门课写什么样的测试?

您可能会编写测试来验证这一点,给定 Email , 调用 accept()确实调用了 appendBody()使用适当的参数,也许用 null 调用它参数抛出 NullPointerException等等。您可能不会验证 email.appendBody()按预期工作,因为 Email 的测试涵盖了这一点.您可能需要模拟 Email对于这些测试,如果很难创建。

好吧,所有这些测试也可以针对 lambda 执行。您的问题是工厂和创建对象的类型都是私有(private)的,因此从测试的角度来看,访问该对象的唯一方法是通过传递给(模拟)emailBuilder.buildEmail() 的参数。 .

如果你使用 Mockito 模拟 emailBuilder ,您可以通过 ArgumentCaptor 捕获此方法的参数s(参见 15. Capturing arguments for further assertions (Since 1.8.0)),我相信其他模拟库也提供类似的功能。

关于java - 测试依赖项调用的 lambda 表达式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54308063/

相关文章:

java - 在单个 Java 语句中创建 JTextField 对象时设置其对象

c++ - 对 DLL 中的非导出类进行单元测试

unit-testing - 如何在 Android Studio 中分析测试?

c++ - LAMBDA错误: conditional expression of type 'void' is illegal

c++ - 如何在 C++ 中提供像 lambda 这样的可调用对象保护访问?

java - ArrayAdapter刷新数据

java - 有没有更快的方法来检查列表中的某个项目是否大于、小于、等于某个数字?

java - 获取 Android 应用程序使用的数据/信息

unit-testing - 在 visual studio 上使用 Resharper 调试单元测试时出现 FatalExecutionEngineError

python - PySpark 在映射 lambda 中序列化 'self' 引用对象?