替换实例化类的实现而不用触摸代码(java) [英] Replace implementation of instantiated class without to touch code (java)
问题描述
我有遗留代码,我不想接触。
public class LegacyCode {
public LegacyCode ){
Service s = new ClassA();
s.getMessage();
}
}
其中 ClassA
提供CORBA服务调用。
public class ClassA implements Service {
@Override
public String getMessage(){
// Make CORBA service call ...
returnA类;
}
}
接口 Service
看起来像;
public interface Service {
String getMessage
}
为了测试的目的,我想替换
public class ClassB implements Service {
@Override
public String getMessage(){
returnStub Class B;
}
}
到目前为止很好。但是在所示的传统代码中可以不加修改地在实例化时加载
? ClassB
而不是 ClassA
c $ c> ClassA
//在我的测试工作台
new LegacyCode //Stub Class B
我试图写一个自定义类加载器,由java vm参数启动,但只有第一个类(此处 LegacyCode
)由该加载程序加载。
使用 PowerMock
,您可以创建一个模拟(或存根)用于构造函数代码。答案取自此链接。我会尝试将其转换为与您的用例完全匹配:
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassA.class)
public class LegacyTester {
@Test
public void testService(){
//注入你的stub
PowerMock.createMock类);
Service stub = new MyServiceStub();
PowerMock.expectNew(ClassA.class).andReturn(stub);
PowerMock.replay(stub,ClassA.class);
//在这里实现测试逻辑
LegacyCode legacyCode = new LegacyCode();
//实现测试步骤
//调用验证,如果你想确保ClassA构造函数被调用
PowerMock.verify(stub,ClassA.class)
}
}
这样你注入stub时调用 ClassA
构造函数,而不更改旧代码。希望这是你需要的。
I have legacy code I don't want to touch.
public class LegacyCode{
public LegacyCode() {
Service s = new ClassA();
s.getMessage();
}
}
Where ClassA
provides a CORBA service call.
public class ClassA implements Service{
@Override
public String getMessage() {
// Make CORBA service call...
return "Class A";
}
}
And the interface Service
looks like;
public interface Service {
String getMessage();
}
For test purposes, I want to replace the implementation of Service
(in LegacyCode
implemented by ClassA
) with a stub.
public class ClassB implements Service {
@Override
public String getMessage() {
return "Stub Class B";
}
}
So far so good. But is it possible without any modifications at the shown legacy code to load ClassB
instead of ClassA
at the instantiation of ClassA
?
// In my test workbench
new LegacyCode(); // "Stub Class B"
I've tried to write a custom classloader and load it at application start by java vm arguments but only the first class (here LegacyCode
) was loaded by that loader.
Thanks in advance
Using PowerMock
you can create a mock (or stub) for a constructor code. The answer is taken from this link. I'll try to convert it to match exactly to your use case:
@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassA.class)
public class LegacyTester {
@Test
public void testService() {
// Inject your stub
PowerMock.createMock(ClassA.class);
Service stub = new MyServiceStub();
PowerMock.expectNew(ClassA.class).andReturn(stub);
PowerMock.replay(stub, ClassA.class);
// Implement test logic here
LegacyCode legacyCode = new LegacyCode();
// Implement Test steps
// Call verify if you want to make sure the ClassA constructor was called
PowerMock.verify(stub, ClassA.class)
}
}
This way you inject your stub when the call to ClassA
constructor happens, without changing the legacy code. Hope that's what you needed.
这篇关于替换实例化类的实现而不用触摸代码(java)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!