替换实例化类的实现而不用触摸代码(java) [英] Replace implementation of instantiated class without to touch code (java)

查看:167
本文介绍了替换实例化类的实现而不用触摸代码(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屋!

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