java 我可以模拟超类方法调用吗?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/622763/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-29 13:06:20  来源:igfitidea点击:

Can I mock a super class method call?

javatddmockingeasymockjmock

提问by arielsan

Sometimes, you want to test a class method and you want to do an expectation on a call of a super class method. I did not found a way to do this expectation in java using easymock or jmock (and I think it is not possible).

有时,您想测试一个类方法,并希望对超类方法的调用进行期望。我没有找到使用 easymock 或 jmock 在 java 中实现此期望的方法(我认为这是不可能的)。

There is a (relative) clean solution, to create a delegate with the super class method logic and then set expectations on it, but I don't know why and when use that solution ?any ideas/examples?

有一个(相对)干净的解决方案,用超类方法逻辑创建一个委托,然后对其设置期望,但我不知道为什么以及何时使用该解决方案?有什么想法/例子吗?

Thanks

谢谢

采纳答案by Cem Catikkas

Well, you can if you want to. I don't know if you are familiar with JMockit, go check it out. The current version is 0.999.17 In the mean time, let's take a look at it...

好吧,如果你愿意,你可以。不知道大家是否熟悉JMockit,去看看吧。当前版本是 0.999.17 同时,让我们来看看它......

Assume the following class hierarchy:

假设以下类层次结构:

public class Bar {
    public void bar() {
        System.out.println("Bar#bar()");
    }
}

public class Foo extends Bar {
    public void bar() {
        super.bar();
        System.out.println("Foo#bar()");
    }
}

Then, using JMockit in your FooTest.javayou can validate that you're actually making a call to Barfrom Foo.

然后,在您的 JMockit 中使用FooTest.java您可以验证您实际上是在调用Barfrom Foo

@MockClass(realClass = Bar.class)
public static class MockBar {
    private boolean barCalled = false;

    @Mock
    public void bar() {
        this.barCalled = true;
        System.out.println("mocked bar");
    }
}

@Test
public void barShouldCallSuperBar() {
    MockBar mockBar = new MockBar();
    Mockit.setUpMock(Bar.class, mockBar);

    Foo foo = new Foo();
    foo.bar();

    Assert.assertTrue(mockBar.barCalled);

    Mockit.tearDownMocks();
}

回答by Oliver Hernandez

Expanding on @Cem Catikkas answer, using JMockit 1.22:

使用 JMockit 1.22 扩展 @Cem Catikkas 答案:

@Test
public void barShouldCallSuperBar() {
    new MockUp<Bar>() {
        @Mock
        public void bar() {
            barCalled = true;
            System.out.println("mocked bar");
        }
    };

    Foo foo = new Foo();
    foo.bar();

    Assert.assertTrue(mockBar.barCalled);
}

No need for the static class annotated with @MockClass, it is replaced by the MockUp class.

不需要@MockClass注解的静态类,用MockUp类代替。

回答by Jon Skeet

I don't think I'd mock out a super call - it feels to me like the behaviour there is part of the behaviour of the class itself, rather than the behaviour of a dependency. Mocking always feels like it should be to do with dependencies more than anything else.

我不认为我会模拟超级调用 - 在我看来,这种行为是类本身行为的一部分,而不是依赖项的行为。Mocking 总是感觉它应该与依赖关系比其他任何事情都重要。

Do you have a good example of the kind of call you want to mock out? If you want to mock out a call like this, would it be worth considering composition instead of inheritance?

你有一个很好的例子来说明你想要模拟的那种电话吗?如果您想模拟这样的调用,是否值得考虑组合而不是继承?

回答by Rogério

There are several tests that do just that (ie specify an expected invocation on a super-class method) using the JMockit Expectations API, in the Animated Transitions sample test suite. For example, the FadeInTesttest case.

在 Animated Transitions 示例测试套件中,有几个测试使用 JMockit Expectations API 来做到这一点(即指定对超类方法的预期调用)。例如,FadeInTest测试用例。

回答by Vazha Amiranashvili

No, there is no way of mocking super class methods with jMock.

不,没有办法用jMock 模拟超类方法。

However there is a quick-and-dirty solution to your problem. Suppose you have class A and class B extends A. You want to mock method A.a() on B. You can introduce class C extends B in your test code and override the method C.a() (just call super, or return null, id does not matter). After that mock C and use the mock everywhere, where you'd use B.

但是,有一个快速而肮脏的解决方案可以解决您的问题。假设您有类 A 和类 B 扩展 A。您想在 B 上模拟方法 Aa()。您可以在测试代码中引入类 C 扩展 B 并覆盖方法 Ca()(只需调用 super,或返回 null,id不要紧)。在那之后模拟 C 并在任何地方使用模拟,在那里你会使用 B。

回答by Steve Freeman

intercepting a super call is much too fine-grained. Don't overdo the isolation.

拦截超级调用太细粒度了。不要过度隔离。