测试依赖项调用的lambda表达式 [英] Test lambda expressions called by dependencies

查看:68
本文介绍了测试依赖项调用的lambda表达式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在lambda表达式中测试一些代码,这是另一个类的回叫.

I am trying to test some code inside lambda expression which is a call back from another class.

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);
}

EmailBuilder调用方法getBodyContent中的lambda表达式,这是JUnit测试中对EmailSender的模拟依赖项.由于我在嘲笑EmailBuilder的行为,因此不会从测试中调用getBodyContent中的代码.如何测试这样的作品?

The lambda expression in the method getBodyContent is called from EmailBuilder which is a mocked dependency in the JUnit test for EmailSender. Since I am mocking the behavior of EmailBuilder, the code inside getBodyContentis not called from tests. How to test such piece?

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

Capturing the lambda expression through Argument Captors is not a solution in this case as the behavior of EmailBuilder is mocked and the actual methods are not called. Secondly, email.appendBody does some transformations on an object which is passed by an external API and not straightforward to create.

推荐答案

在这里您要做的实际上是验证工厂方法确实确实返回了正确的对象.有一个此相关问题,其中共识是除了验证确实返回正确类型的对象外,不要测试工厂方法的结果.该对象的行为应在UnitTests中针对该类型进行测试.

What you are trying to do here is essentially to verify that a factory method did in fact really return the correct object. There is this related question, where the consensus is to not test the result of a factory method beyond verifying that it does indeed return an object of the correct type. The behavior of that object should be tested in the UnitTests for that type.

有关单元测试lambda的相关问题的答案中斯图尔特·马克斯(Stuart Marks)认为

In an answer to this related question on unit testing lambdas Stuart Marks argues that

如果lambda中的代码足够复杂以至于需要进行测试,那么也许应该将该代码重构出lambda,以便可以使用常规技术对其进行测试.

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,而是实现功能接口Consumer<Email>的具体类MyBodyContentAppender,您将如何对其进行单元测试?您将为该课程写什么样的测试?

Now, the real question is: If this was not a lambda, but a concrete class MyBodyContentAppender that implements the functional interface Consumer<Email>, how would you unit test that? What kinds of test would you write for this class?

您可能会编写测试来验证,在给定Email的情况下,调用accept()确实确实使用适当的参数调用了appendBody(),也许是通过null参数调用它引发了NullPointerException等.您可能验证email.appendBody()是否按预期工作,因为Email的测试已涵盖了该内容.如果难以创建,可能必须模拟Email进行这些测试.

You would probably write tests to verify that, given an Email, invoking accept() does indeed invoke appendBody() with the appropriate parameters, perhaps that invoking it with a null argument throws a NullPointerException etc. You would possibly not verify that email.appendBody() works as expected, because that is covered by the tests for Email. You may have to mock Email for these tests if it is difficult to create.

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

Well, all of these tests can also be performed for the lambda. Your problem is that the factory and the type of the created object are both private, so from the perspective of your test, the only way to access that object is via the parameter passed to the (mocked) emailBuilder.buildEmail().

如果使用Mockito模拟emailBuilder,则可以通过ArgumentCaptor s捕获此方法的参数(请参见.捕获进一步断言的参数(自1.8.0起)),我确定其他模拟库都可以提供类似的功能.

If you use Mockito for mocking the emailBuilder, you could capture the arguments to this method via ArgumentCaptors (see 15. Capturing arguments for further assertions (Since 1.8.0)), I'm sure other mocking libraries provide similar functionality.

这篇关于测试依赖项调用的lambda表达式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆