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

时间:2009-03-07 23:54:39

标签: java tdd mocking easymock jmock

有时候,你想测试一个类方法,并且想要调用超类方法。我没有找到一种方法来使用easymock或jmock在java中做这个期望(我认为这是不可能的)。

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

由于

6 个答案:

答案 0 :(得分:12)

嗯,如果你愿意,你可以。我不知道您是否熟悉JMockit,请查看。目前的版本是0.999.17。与此同时,我们来看看它......

假设以下类层次结构:

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()");
    }
}

然后,在FooTest.java中使用JMockit,您可以验证您是否实际从Bar拨打了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();
}

答案 1 :(得分:5)

使用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);
}

不需要使用@MockClass注释的静态类,它将被MockUp类替换。

答案 2 :(得分:4)

我不认为我会模拟一个超级调用 - 我觉得这种行为是类本身行为的一部分,而不是依赖行为。模拟总是感觉它应该与依赖关系相比更多。

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

答案 3 :(得分:1)

在Animated Transitions示例测试套件中,有几个测试可以使用JMockit Expectations API执行此操作(即在超类方法上指定预期的调用)。例如,FadeInTest测试用例。

答案 4 :(得分:1)

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

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

答案 5 :(得分:-1)

拦截超级电话太精细了。不要过度隔离。