gpt4 book ai didi

java - 模拟父 final方法

转载 作者:行者123 更新时间:2023-12-02 03:32:48 25 4
gpt4 key购买 nike

我想模拟一个继承的子类方法。这个方法不能被重写,因为它是最终的。当使用“when,thenReturn”时,mockito正在调用真正的方法,这会导致一些异常,我想避免这种情况。

class A{
final String doSomething()
{
//Some treatement
return "";
}
}
class B extends A{
//
}

class TestB {
@Test
public void test(){}
B b=mock(B.class);
when(B.doSomething()).thenReturn("");// it fails because it calls //the real method of A
}

}

最佳答案

提出这个问题有两个原因:

a) 您正在处理某种您无法更改的第三方库/设计;但你想以某种方式进行测试。在这种情况下,使用 PowerMock 可能是一种选择,因为 PowerMock 操作字节代码并使模拟 final方法/类成为可能。但是:PowerMock 因制造各种奇怪的问题而闻名;说真的:你最好不要使用它。

b) 你的“单元测试”是错误的:你从不创建 B 类的模拟对象来测试 B 类上的某些内容。你只模拟你的对象 X、Y、Z。 B 中的代码需要做一些事情。

所以,你真正的问题是:你在 B 上有一些你想要测试的方法“doSomethingElse()”。并且“doSomethingElse()”调用“doSomething()”......并且您的测试失败,因为您无法控制“doSomething()”的行为。有两种选择可以解决这个问题:

1)你真的需要继承吗? B 必须真正扩展 A,还是 B 对象……简单地拥有 A 对象会更好? (如果是这样,您可以模拟该 A 对象并获得对其方法的控制)。听说过CoI

2)你反转依赖关系;就像:

abstract class A { 
final void doSomething() { doSomethingSpecific() ... }
abstract void doSomethingSpecific();
}

class B extends A { @Override void doSomethingSpecific() { ...

为您的“测试”问题提供“正确的面向对象”解决方案。

此外:如果“doSomething()”在 A 类上是最终的,那么这应该是为了实现 OCP :您在 A 上定义了子类可以使用(或间接使用)的某些行为,并且不应更改。因此,您可以返回到您的设计,也许最终是“出于错误的原因”添加的,那么只需删除关键字就可以了。

关于java - 模拟父 final方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37854504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com