如何模拟依赖于输入值的依赖项?
How to mock dependencies that depend on input value?
我想对这样的方法进行单元测试:
public String handleRequest(Event event) {
for(Message msg : event.getRecords()){
SDKClient client = new SDKClient(msg.getUser(), msg.getPassword());
String output = client.makeAPICall();
return output.toUpperCase();
}
}
}
通常,我们通过将它们作为参数传递并在 Junit/Mockito 中模拟它们来模拟 SDKClient
之类的依赖项。但是,在这种情况下,我不能只传递它,因为 SDKClient
取决于传入的实际事件。还有一个未确定的客户端数量,一个对应 event
中的每条消息。我想对整个方法进行单元测试,但我事先不知道依赖关系。可能吗?
在这种情况下,您传入的是某种抽象了 new SDKClient
调用的函数:
interface SdkClientProvider {
SDKClient(String user, String password);
}
在这种特殊情况下,如果您愿意,可以使用 BiFunction<String, String, SDKClient>
。
由于 new SDKClient
可能是此 class 的唯一“实时”实现,您甚至可以这样做:
class MyService {
@Setter
private BiFunction<String, String, SDKClient> createClient = SDKClient::new;
...
}
这种模式在依赖于系统时很常见java.time.Clock
。
(请注意,“创建、使用和处置服务对象”是一个非常有问题的设计,除非您坚持使用某些 badly-designed 外部库,否则它会要求重构。)
我想对这样的方法进行单元测试:
public String handleRequest(Event event) {
for(Message msg : event.getRecords()){
SDKClient client = new SDKClient(msg.getUser(), msg.getPassword());
String output = client.makeAPICall();
return output.toUpperCase();
}
}
}
通常,我们通过将它们作为参数传递并在 Junit/Mockito 中模拟它们来模拟 SDKClient
之类的依赖项。但是,在这种情况下,我不能只传递它,因为 SDKClient
取决于传入的实际事件。还有一个未确定的客户端数量,一个对应 event
中的每条消息。我想对整个方法进行单元测试,但我事先不知道依赖关系。可能吗?
在这种情况下,您传入的是某种抽象了 new SDKClient
调用的函数:
interface SdkClientProvider {
SDKClient(String user, String password);
}
在这种特殊情况下,如果您愿意,可以使用 BiFunction<String, String, SDKClient>
。
由于 new SDKClient
可能是此 class 的唯一“实时”实现,您甚至可以这样做:
class MyService {
@Setter
private BiFunction<String, String, SDKClient> createClient = SDKClient::new;
...
}
这种模式在依赖于系统时很常见java.time.Clock
。
(请注意,“创建、使用和处置服务对象”是一个非常有问题的设计,除非您坚持使用某些 badly-designed 外部库,否则它会要求重构。)