You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在测试B类时Mock父类protected方法的super调用?

How to Mock the super.doSomething() Call in Subclass B for Testing

Hey there, let's figure out how to skip testing the parent class A's doSomething() logic when you're testing subclass B. This is a common scenario when you want to focus solely on B's implementation without getting tangled up in A's code. Here are two reliable approaches:


Option 1: Mockito + Reflection (No Extra Libraries Needed)

Mockito doesn't natively support mocking parent class protected methods, but we can work around this with reflection to bypass access restrictions. Here's how:

  • We'll use a Spy for B, which lets us keep B's own doSomething() logic while stubbing out the parent's version.
  • Use reflection to make A's protected doSomething() method accessible, then tell Mockito to do nothing when it's called.

Here's the code example:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Spy;
import org.mockito.junit.MockitoJUnitRunner;
import java.lang.reflect.Method;
import static org.mockito.Mockito.doNothing;

@RunWith(MockitoJUnitRunner.class)
public class BTest {

    @Spy
    private B bInstance = new B();

    @Test
    public void testDoSomethingWithoutSuperLogic() throws Exception {
        // Grab the protected doSomething method from parent class A
        Method parentDoSomething = A.class.getDeclaredMethod("doSomething");
        parentDoSomething.setAccessible(true);

        // Stub the parent method to do nothing when called
        doNothing().when(bInstance, parentDoSomething).invoke();

        // Call B's doSomething method
        bInstance.doSomething();

        // Now you can run assertions on B's behavior without A's code interfering
    }
}

Option 2: PowerMock (More Straightforward for Parent Class Mocks)

If you don't mind adding an extra library, PowerMock makes this way simpler by handling bytecode manipulation to intercept parent class calls.

First, add PowerMock dependencies matching your Mockito version (e.g., powermock-module-junit4 and powermock-api-mockito2). Then:

  • Annotate your test class to use PowerMock's runner and prepare B for bytecode changes.
  • Either suppress A's doSomething() entirely or stub it with custom logic.

Example code:

import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(B.class) // Required to modify B's bytecode
public class BTest {

    @Test
    public void testDoSomethingWithSuperMocked() {
        B bInstance = new B();

        // Option 1: Suppress A's doSomething so it doesn't run at all
        PowerMockito.suppress(PowerMockito.method(A.class, "doSomething"));

        // Option 2: Stub it with custom logic if needed
        // PowerMockito.doAnswer(invocation -> {
        //     // Your mock behavior here (e.g., log something, return a value)
        //     return null;
        // }).when(bInstance).doSomething();

        // Execute B's method
        bInstance.doSomething();

        // Assert your expectations for B's implementation
    }
}

Quick Notes:

  • For the Mockito+reflection approach, double-check the method signature (including parameters) if doSomething takes arguments—you'll need to match them in getDeclaredMethod.
  • PowerMock is great for complex scenarios, but it does add some overhead. Stick with Mockito+reflection if you want to keep your dependency list lean.

内容的提问来源于stack exchange,提问作者P.Zaw

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:29:26