Java 如何测试函数';当它';s作为方法参数传递?

Java 如何测试函数';当它';s作为方法参数传递?,java,lambda,jmockit,Java,Lambda,Jmockit,是否可以测试在方法过程中传递的lambda函数中编写的代码 @allargsconstuctor 公共类JsonController{ 私有最终JsonElementProcessingService JsonElementProcessingService; 私有最终JsonObjectProcessingService JsonObjectProcessingService; 私有最终JsonArrayProcessingService JsonArrayProcessingService;

是否可以测试在方法
过程中传递的lambda函数中编写的代码

@allargsconstuctor
公共类JsonController{
私有最终JsonElementProcessingService JsonElementProcessingService;
私有最终JsonObjectProcessingService JsonObjectProcessingService;
私有最终JsonArrayProcessingService JsonArrayProcessingService;
公共void进程(字符串rawJson){
jsonElementProcessingService.process(json->{
JsonElement元素=新的JsonParser().parse(json);
if(element.isJsonArray()){
返回jsonArrayProcessingService.process(element.getAsJsonArray());
}否则{
返回jsonObjectProcessingService.process(element.getAsJsonObject());
}
},rawJson);
}
}
由于lambda是惰性的,所以当我调用
JsonController::process
时不会调用函数(
function::apply
),那么有没有办法检查调用了
jsonaryprocessingservice::process

@RunWith(JMockit.class)
公共类JsonControllerTest{
@注射的
私有JsonElementProcessingService JsonElementProcessingService;
@注射的
私有JsonObjectProcessingService JsonObjectProcessingService;
@注射的
私有JsonArrayProcessingService JsonArrayProcessingService;
@测试
私有JsonController JsonController;
@试验
公开无效测试(){
进程(“[{\”键\“:1}]”);
//这里如何检查调用了jsonArrayProcessingService?
}
}
只需将其转换为方法,使其可测试(和可读):

public void process(String rawJson) {
    jsonElementProcessingService.process(this::parse, rawJson);
}

Object parse(String json) {
    JsonElement element = new JsonParser().parse(json);
    if (element.isJsonArray()) {
        return jsonArrayProcessingService.process(element.getAsJsonArray());
    } else {
        return jsonObjectProcessingService.process(element.getAsJsonObject());
    }
}
我个人遵循的相关指导原则是:

  • 只要我的lambda需要花括号,就将它们转换为方法
  • 组织代码以便可以对其进行单元测试
您可能需要更改
parse
方法的返回类型,以匹配您的处理服务(未显示)返回的任何内容。

只需将其转换为方法,使其可测试(和可读):

public void process(String rawJson) {
    jsonElementProcessingService.process(this::parse, rawJson);
}

Object parse(String json) {
    JsonElement element = new JsonParser().parse(json);
    if (element.isJsonArray()) {
        return jsonArrayProcessingService.process(element.getAsJsonArray());
    } else {
        return jsonObjectProcessingService.process(element.getAsJsonObject());
    }
}
我个人遵循的相关指导原则是:

  • 只要我的lambda需要花括号,就将它们转换为方法
  • 组织代码以便可以对其进行单元测试

您可能需要更改
parse
方法的返回类型,以匹配您的处理服务(未显示)返回的内容。

鉴于其相对基本的重定向逻辑,您是否只想确认调用了
@Injectable
中的哪一个

@测试
公开无效测试(){
进程(“[{\”键\“:1}]”);
新的核查(){{
jsonArrayProcessingService.process(带有instanceof(JsonArray.class));
}};
}

鉴于其相对基本的重定向逻辑,您是否只想确认调用了
@Injectable
中的哪一个:

@测试
公开无效测试(){
进程(“[{\”键\“:1}]”);
新的核查(){{
jsonArrayProcessingService.process(带有instanceof(JsonArray.class));
}};
}

实际上,我确实需要使用传递函数的方法,因为只有在某些条件合适时才会调用它。@kbo方法引用(我编码为
this::parse
)是
函数。它与lambda在各个方面都是相同的,除了它的名称。您的示例将代码公开,据我所知,您建议直接测试方法解析,但这不是我想要的,然后将其包私有化(请参见编辑的代码),并在同一包中使用测试对其进行测试。或者将其私有化并使用groovy/Spock对其进行测试。这是测试代码的唯一(也是最好的)方法。我不能做任何重构,所以问题仍然是,实际上我确实需要使用传递函数的方法,因为只有在某些条件合适时才会调用它。@kbo方法引用(我编码为
This::parse
)是
函数。它与lambda在各个方面都是相同的,除了它的名称。您的示例将代码公开,据我所知,您建议直接测试方法解析,但这不是我想要的,然后将其包私有化(请参见编辑的代码),并在同一包中使用测试对其进行测试。或者将其私有化并使用groovy/Spock对其进行测试。这是测试代码的唯一(也是最好的)方法。我无法进行任何重构,所以问题仍然存在。我不熟悉
jmockit
,但我认为在您的情况下,正确的步骤应该是:“运行UUT方法,从模拟依赖项中注入lambda,运行它,根据您传递的json验证是否调用了正确的模拟。”主要原因是,您必须首先验证调用了正确的
JsonElementProcessingService
方法,然后通过调用它来验证传递的lambda是否执行了正确的细化。我不熟悉
jmockit
,但我认为在您的情况下,正确的步骤应该是:“运行UUT方法,从模拟依赖项中注入lambda,运行它,根据您传递的json验证是否调用了正确的模拟。”主要原因是您必须首先验证调用了正确的
JsonElementProcessingService
方法,然后通过调用它来验证传递的lambda是否执行了正确的细化。