java - 在不接触代码的情况下替换实例化类的实现(java)

标签 java unit-testing constructor dependency-injection classloader

我有不想触及的遗留代码。

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...
       return "Class A";
    }
}

接口(interface)Service看起来像;

public interface Service {
    String getMessage();
}

出于测试目的,我想用 stub 替换 Service 的实现(在 ClassA 实现的 LegacyCode 中)。

public class ClassB implements Service {
    @Override
    public String getMessage() {
        return "Stub Class B";
    }
}

到目前为止一切顺利。但是,是否可以在不对显示的遗留代码进行任何修改的情况下在 ClassA 的实例化时加载 ClassB 而不是 ClassA

// In my test workbench
new LegacyCode(); // "Stub Class B"

我尝试编写一个自定义类加载器并在应用程序启动时通过 java vm 参数加载它,但该加载器仅加载了第一个类(此处为 LegacyCode)。

提前致谢

最佳答案

使用 PowerMock 您可以为构造函数代码创建模拟(或 stub )。答案取自this link .我会尝试将其转换为与您的用例完全匹配:

@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)
    }
}

通过这种方式,您可以在调用 ClassA 构造函数时注入(inject) stub ,而无需更改遗留代码。希望这就是您所需要的。

关于java - 在不接触代码的情况下替换实例化类的实现(java),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19307121/

相关文章:

java - Netbeans 10.0 无法在 Windows 10 操作系统中启动

带有 MCRYPT_RIJNDAEL_256 密码的 mcrypt_encrypt PHP 函数的 Java 代码

我们可以使用 googletest (gtest) 来测试 C 代码吗

python - 是否可以使用 pytest 测试 while True 循环(我尝试超时)?

.net - 是否可以仅将ReSharper用作测试运行器?

c++ - 为什么我们不能在声明时初始化类成员?

java - 验证两个字符串之间的用户输入?

java - 如何跳过所有模块的 javadoc?

c++ - 从 C 字符串构造 std::string 与从另一个 std::string 构造不一致

javascript - 模块模式中的构造函数