模拟/测试子类中的超类调用..可能吗?

发布于 2024-12-21 07:45:09 字数 314 浏览 3 评论 0原文

我正在寻找一种解决方案来模拟子类 ButtonClicker 中的超级调用。

Class Click {
      public void buttonClick() throws java.lang.Exception { /* compiled code */ }     } 

Class ButtonClicker extends Click { 
    @Override
    public void buttonClick() throws Exception {

        super.buttonClick();
    } }

I am looking for a solution to mock the super call in subclass ButtonClicker.

Class Click {
      public void buttonClick() throws java.lang.Exception { /* compiled code */ }     } 

Class ButtonClicker extends Click { 
    @Override
    public void buttonClick() throws Exception {

        super.buttonClick();
    } }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

成熟稳重的好男人 2024-12-28 07:45:09

使用继承会降低代码的可测试性。考虑用 委托 替换继承并模拟委托。

提取接口IClicker

interface IClicker {
    void buttonClick();
}

Clicker 类中实现IClicker。如果您正在使用第三方代码,请考虑使用 适配器模式

重写您的 ButtonClicker 如下:

class ButtonClicker implements IClicker {
    Clicker delegate;

    ButtonClicker(Clicker delegate) {
        this.delegate = delegate;
    }

    @Override
    public void buttonClick() throws Exception {
        delegate.buttonClick();
    }

}

现在只需将模拟作为构造函数参数传递:

Clicker mock = Mockito.mock(Clicker.class);
// stubbing here
ButtonClicker buttonClicker = new ButtonClicker(mock);

Using inheritance reduces testability of your code. Consider replacing inheritance with the delegation and mock the delegate.

Extract the interface IClicker

interface IClicker {
    void buttonClick();
}

Implement IClicker in Clicker class. In case that you are working with third-party code consider using Adapter Pattern

Rewrite your ButtonClicker as following:

class ButtonClicker implements IClicker {
    Clicker delegate;

    ButtonClicker(Clicker delegate) {
        this.delegate = delegate;
    }

    @Override
    public void buttonClick() throws Exception {
        delegate.buttonClick();
    }

}

Now just pass the mock as a constructor parameter:

Clicker mock = Mockito.mock(Clicker.class);
// stubbing here
ButtonClicker buttonClicker = new ButtonClicker(mock);
找个人就嫁了吧 2024-12-28 07:45:09

答案是否定的。模拟只是一个简单的接口实现。 (我指的是 API 意义上的接口,而不是特定的 Java 关键字意义上的接口。)因此它不知道任何实现细节,例如哪个类实际实现了该功能(本质上没有功能)。

您可以在真实对象上创建一个“间谍”,它只允许您模拟某些方法而不是其他方法,但这也不允许您仅模拟类的超级方法,因为您选择模拟的方法通常是由签名选择,对于子类和超类都是相同的。

The answer is no. A mock is only a trivial interface implementation. (I mean interface in the API sense, not the specific Java keyword sense.) So it doesn't know about any implementation details like which class actually implements the functionality (there is no functionality, essentially).

You can create a 'spy' on a real object that will let you mock only some methods and not others, but that also will not let you mock just the super method of a class because the method(s) you choose to mock are typically chosen by the signature, which is the same for both the sub class and the super class.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文