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

Spring Boot中用Mockito编写Repository的JUnit测试遇空指针问题求助

解决Repository测试空指针及正确测试方案

现有代码的问题

  1. Mock未初始化:仅用@Mock注解但未触发Mockito的初始化逻辑,导致repository实例为null。
  2. 类型错误:声明的Repository是泛型父类,应该用具体的AddressRepo类型,否则无法调用getAdressResults()方法。
  3. 实体方法调用错误:实体类里的方法是setId(),你写的setid(1))存在语法错误(多了闭合括号+方法名大小写错误)。

方案一:Mock测试(验证方法调用逻辑,无需真实数据库)

这种方式适合快速测试业务层对Repository的调用逻辑,不涉及真实SQL执行:

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import java.util.ArrayList;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

@ExtendWith(MockitoExtension.class) // 初始化Mockito的Mock对象
public class AddressRepoMockTest {

    @Mock // 声明具体的AddressRepo类型
    private AddressRepo addressRepo;

    @Test
    public void testGetAddressResults() {
        // 构造测试数据
        Address address = new Address();
        address.setId(1); // 修正方法名和语法
        address.setLine1("address line 1");

        List<Address> addressList = new ArrayList<>();
        addressList.add(address);

        // Mock方法返回值
        when(addressRepo.getAdressResults()).thenReturn(addressList);

        // 调用方法并断言
        List<Address> addresses = addressRepo.getAdressResults();
        assertThat(addresses.get(0).getLine1()).isEqualToIgnoringCase("address line 1");
    }
}

方案二:集成测试(验证SQL正确性,用真实测试数据库)

如果要验证@Query里的SQL是否正确执行,需要用集成测试,Spring提供了@DataJpaTest注解自动配置测试环境(默认用H2内存数据库):

1. 先修正Repository的泛型错误

你的AddressRepo继承JpaRepository时用了SourceAddress,但实体类是Address,这里明显是笔误,先修正:

@Repository
public interface AddressRepo extends JpaRepository<Address, Integer>, JpaSpecificationExecutor<Address> {

    @Query(value = "select * from ADDRESS", nativeQuery = true) // 表名和实体类@Table一致,去掉多余空格
    List<Address> getAdressResults();
}

2. 编写集成测试类

import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;

@DataJpaTest // 自动配置JPA测试环境,创建内存数据库
public class AddressRepoIntegrationTest {

    @Autowired // 注入真实的AddressRepo代理实例
    private AddressRepo addressRepo;

    @Test
    public void testGetAddressResults() {
        // 先往测试数据库插入数据
        Address testAddress = new Address();
        testAddress.setLine1("address line 1");
        testAddress.setLine2("line 2");
        addressRepo.save(testAddress);

        // 调用Repository方法
        List<Address> addresses = addressRepo.getAdressResults();

        // 断言结果
        assertThat(addresses).isNotEmpty();
        assertThat(addresses.get(0).getLine1()).isEqualToIgnoringCase("address line 1");
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 18:33:25