最好能够构造一个真实的ThirdPartyObject
.
由于您需要引用此类,因此您的类路径中至少有一些包含此类的第 3 方库。您确定没有办法构建它,例如使用图书馆中的工厂吗?或者通过构造另一个对象并调用一个方法,该方法将使用ThirdPartyObject
实例调用您的插件?
虽然这有时称为集成测试(因为您正在测试与主应用程序的集成),但它也可以被视为经典意义上的单元测试,只要测试不将数据放入数据库或做任何其他事情这可能会影响其他测试。
如果上述方法不可行,您可以求助于模拟,ThirdPartyObject
例如使用Mockito。尽量确保您的测试代码与您的实现的耦合没有超出它的需要。有些人认为他们需要模拟一个类的所有依赖项,然后验证对这些依赖项的所有方法调用。他们引入了很多强耦合和冗余。
关于您提到的两个问题,有两种方法可以解决:
1)你说你不能实现ThirdPartyObject
一个接口。没错,但是您可以编写一个适配器来实现此接口并委托给ThirdPartyObject
. 然后主应用程序调用的方法将简单地委托给使用此接口的实际插件方法实现。
示例(假设ThirdPartyObject
有一个方法void thirdPartyMethodCall()
:
public interface InterfaceForThirdPartyObject {
void thirdPartyMethodCall();
}
public class ThirdPartyObjectAdapter implements InterfaceForThirdPartyObject {
private final ThirdPartyObject delegate;
public ThirdPartyObjectAdapter(ThirdPartyObject delegate) {
this.delegate = delegate;
}
public void thirdPartyMethodCall() {
delegate.thirdPartyMethodCall();
}
}
// your actual plugin implementation, not directly exposed to the main app
public class MyPlugin {
public PerSpecResponseObject myPluginFunction(InterfaceForThirdPartyObject iUseThis){
// this will contain your actual logic that you want to test
}
}
// this is the plugin as exposed to the main app
public class MyPluginAdapter implements PluginInterface {
private final MyPlugin delegate = new MyPlugin();
// this is called by the main application
public PerSpecResponseObject myPluginFunction(ThirdPartyObject iUseThis) {
delegate.myPluginFunction(new ThirdPartyObjectAdapter(iUseThis));
}
}
2)您说您不能子类ThirdPartyObject
化,因为插件实现了一个接口,该接口具有ThirdPartyObject
as 方法参数而不是? extends ThirdPartyObject
. 我不明白为什么会出现问题:采用ThirdPartyObject
as 参数的方法将很乐意采用ThirdPartyObject
.