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

Mockito深度对象Mock:如何无需Getter实现属性方法Mock

Solutions for Mocking Field Access Without Getters in Mockito

Got it, let's tackle this Mockito problem you're facing. The core issue is: when using @Mock A a;, directly calling when(a.list.isEmpty()).thenReturn(true) throws an error because the list field is null on the mocked A instance. Using @Mock(answer = Answers.RETURNS_DEEP_STUBS) fixes the null issue but forces you to use getter methods, which you don't want to add everywhere.

Here are practical workarounds that let you stub the list's behavior without adding getters:

1. Manually Mock the List and Set It via Reflection

You can create a mock for List<B> separately, then use reflection to assign this mock to the list field of your mocked A instance. This bypasses the need for getters entirely.

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.lang.reflect.Field;
import java.util.List;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class)
public class YourTestClass {
    @Mock
    A a;
    
    @Mock
    List<B> mockList;

    @BeforeEach
    void setUp() throws NoSuchFieldException, IllegalAccessException {
        // Access the private/protected list field in class A
        Field listField = A.class.getDeclaredField("list");
        listField.setAccessible(true);
        // Assign the mock list to the field
        listField.set(a, mockList);
        
        // Now you can stub the list's methods directly
        when(mockList.isEmpty()).thenReturn(true);
    }

    @Test
    void yourTest() {
        assert(a.list.isEmpty()); // This will return true as stubbed
    }
}

2. Use Spring's ReflectionTestUtils (If You're in a Spring Project)

If your project uses Spring, ReflectionTestUtils simplifies the reflection boilerplate, making the code cleaner and more readable:

import org.springframework.test.util.ReflectionTestUtils;
// ... other imports

@ExtendWith(MockitoExtension.class)
public class YourTestClass {
    @Mock
    A a;
    
    @Mock
    List<B> mockList;

    @BeforeEach
    void setUp() {
        // Set the mock list into A's field with a single method call
        ReflectionTestUtils.setField(a, "list", mockList);
        
        when(mockList.isEmpty()).thenReturn(true);
    }
}

3. Spy a Real A Instance (If A Can Be Instantiated)

If A has a default constructor or can be easily instantiated, you can spy on a real A object instead of mocking it entirely. Then replace its list field with your mock list:

import org.mockito.Spy;
// ... other imports

@ExtendWith(MockitoExtension.class)
public class YourTestClass {
    @Spy
    A a = new A(); // Spy on a real A instance
    
    @Mock
    List<B> mockList;

    @BeforeEach
    void setUp() throws NoSuchFieldException, IllegalAccessException {
        Field listField = A.class.getDeclaredField("list");
        listField.setAccessible(true);
        listField.set(a, mockList);
        
        when(mockList.isEmpty()).thenReturn(true);
    }
}

All these approaches let you stub the list field's behavior without modifying your original A and B classes to add getters. Pick the one that fits your project setup best!

内容的提问来源于stack exchange,提问作者vinzzz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 10:11:17