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

ari*_*san 15 java tdd easymock mocking jmock

有时,您希望测试一个类方法,并且希望在调用超类方法时进行预期.我没有找到一种方法来使用easymock或jmock在java中做这个期望(我认为这是不可能的).

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

谢谢

Cem*_*kas 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()");
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,在使用JMockit你FooTest.java可以验证你实际上做一个呼叫BarFoo.

@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();
}
Run Code Online (Sandbox Code Playgroud)


Oli*_*dez 6

使用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);
}
Run Code Online (Sandbox Code Playgroud)

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


Jon*_*eet 5

我不认为我会模拟一个超级调用 - 我觉得那里的行为是类本身行为的一部分,而不是依赖的行为。Mocking 总是感觉它应该与依赖关系比什么都重要。

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

  • 是的,但是您想测试隔离的子类,您知道超类工作正常,您不想再次测试它。 (5认同)