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

Spring Boot抽象类子类AirportService的单元测试实现方案

单元测试实现方案

是否需要测试getFileName()?

需要。虽然这个方法仅返回固定字符串,但它是readFromCsv()读取文件的核心依赖项,若文件名指定错误会直接触发文件找不到的异常。测试它能快速验证子类是否正确绑定了目标CSV文件,避免集成阶段才暴露问题。

测试getFileName()

getFileName()是protected方法,若测试类与AirportService在同一包下,可直接调用;若不在同包,通过反射访问即可。

同包测试示例(JUnit 5)

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class AirportServiceTest {

    private final AirportService airportService = new AirportService();

    @Test
    void getFileName_ShouldReturnCorrectFileName() {
        String fileName = airportService.getFileName();
        assertEquals("airport.csv", fileName);
    }
}

跨包反射测试示例

import org.junit.jupiter.api.Test;
import java.lang.reflect.Method;
import static org.junit.jupiter.api.Assertions.assertEquals;

class AirportServiceTest {

    private final AirportService airportService = new AirportService();

    @Test
    void getFileName_ShouldReturnCorrectFileName() throws Exception {
        Method method = AirportService.class.getDeclaredMethod("getFileName");
        method.setAccessible(true);
        String fileName = (String) method.invoke(airportService);
        assertEquals("airport.csv", fileName);
    }
}

测试getData()

getData()的核心逻辑是遍历CsvToBean实例、处理每个AirportBean并返回结果列表。我们可以用Mockito模拟CsvToBean对象,构造测试数据验证处理逻辑是否符合预期。

测试示例(JUnit 5 + Mockito)

import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
import org.junit.jupiter.api.extension.ExtendWith;
import com.opencsv.bean.CsvToBean;
import java.util.List;
import static org.mockito.Mockito.*;
import static org.junit.jupiter.api.Assertions.*;

@ExtendWith(MockitoExtension.class)
class AirportServiceTest {

    private final AirportService airportService = new AirportService();

    @Mock
    private CsvToBean<AirportBean> mockCsvToBean;

    @Test
    void getData_ShouldProcessAndReturnAirportBeans() {
        // 构造模拟业务数据
        AirportBean mockBean1 = new AirportBean();
        mockBean1.setCode("ABC");
        mockBean1.setName("测试机场1");

        AirportBean mockBean2 = new AirportBean();
        mockBean2.setCode("DEF");
        mockBean2.setName("测试机场2");

        // 配置mock对象的迭代器返回模拟数据
        when(mockCsvToBean.iterator()).thenReturn(List.of(mockBean1, mockBean2).iterator());

        // 调用目标方法
        List<AirportBean> result = airportService.getData(mockCsvToBean);

        // 验证结果正确性
        assertEquals(2, result.size());
        assertEquals("ABC", result.get(0).getCode());
        assertEquals("测试机场2", result.get(1).getName());

        // 验证mock对象的方法调用次数
        verify(mockCsvToBean, times(1)).iterator();
    }
}

注意事项

  • 如果getData()包含特定业务逻辑(如字段转换、数据过滤),需构造对应测试场景(例如不符合过滤条件的Bean),验证逻辑是否生效。
  • 确保AirportBean的getter/setter方法正常工作,避免因Bean自身问题导致测试失败。

额外:全流程验证(可选)

若想覆盖完整的CSV读取链路,可在test/resources目录下放置测试用的airport.csv文件,直接调用readFromCsv()验证返回数据与测试文件内容一致,这样能同时验证getFileName()和文件读取逻辑:

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

class AirportServiceTest {

    private final AirportService airportService = new AirportService();

    @Test
    void readFromCsv_ShouldReturnCorrectDataFromTestFile() {
        List<AirportBean> result = airportService.readFromCsv(AirportBean.class, null);
        // 根据测试文件内容断言,示例假设文件有2条数据
        assertEquals(2, result.size());
        assertEquals("JFK", result.get(0).getCode());
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 21:01:19