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

Mockito与Spring Autowired测试:getStudentInfo()需真实调用getAddress()

解决测试中真实调用getAddress()方法的问题

这个问题我之前也碰到过,核心原因是你的测试类里只给Student标注了@InjectMocks,但没有提供Address的有效实例——不管是真实对象还是Spy对象,Mockito都没法凭空创建Address注入到Student里,所以调用getAddress()时才会因为空指针报错。下面是几个能让你真实调用getAddress()的解决方案:

方案1:用@Spy注入真实的Address实例

如果你不需要Spring上下文,只是想让Address执行真实的方法逻辑,可以用Mockito的@Spy注解创建Address的真实实例,它会保留原类的方法行为(除非你主动mock某个方法)。修改后的测试类如下:

import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Spy;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class StudentTest { 
    @InjectMocks
    private Student student; 
    
    @Spy // 用Spy创建真实的Address实例,默认执行真实方法
    private Address address;

    @Test 
    public void testStudentInfo() { 
        String result = student.getStudentInfo("name"); 
        assertNotNull(result); // 添加断言验证结果
    } 
}

方案2:借助Spring测试上下文获取完整Bean

如果Address本身还有Spring依赖(比如它自己也用了@Autowired注入其他类),那直接用Spring Boot的测试上下文来管理Bean更合适,这样所有依赖都会被自动注入:

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import static org.junit.jupiter.api.Assertions.assertNotNull;

@SpringBootTest // 启动Spring上下文
public class StudentTest { 

    @Autowired // 直接从上下文获取已注入Address的Student实例
    private Student student; 

    @Test 
    public void testStudentInfo() { 
        String result = student.getStudentInfo("name"); 
        assertNotNull(result);
    } 
}

方案3:手动创建并注入Address实例

如果你不想依赖Mockito或Spring,也可以手动创建Address的真实对象,再通过反射或者setter方法注入到Student中:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.lang.reflect.Field;
import static org.junit.jupiter.api.Assertions.assertNotNull;

public class StudentTest { 
    private Student student; 
    private Address address;

    @BeforeEach
    void setUp() throws NoSuchFieldException, IllegalAccessException {
        address = new Address(); // 创建真实的Address实例
        student = new Student();
        
        // 用反射注入private的address字段(如果Student没有setter方法的话)
        Field addressField = Student.class.getDeclaredField("address");
        addressField.setAccessible(true);
        addressField.set(student, address);
        
        // 或者如果给Student加了setAddress方法,可以直接调用:
        // student.setAddress(address);
    }

    @Test 
    public void testStudentInfo() { 
        String result = student.getStudentInfo("name"); 
        assertNotNull(result);
    } 
}

补充说明

你原来的测试代码之所以失败,是因为@InjectMocks的作用是把已有的mock/spy对象注入到被测类中,但你既没有给Address标注@Mock/@Spy,也没有手动提供实例,所以Student里的address字段会是null,调用address.getAddress()自然会抛出空指针异常。

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

相关产品推荐
方舟 Agent Plan

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

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