Spring Boot构造方法调用Mock对象方法的测试及JSON转POJO问题
Spring Boot 文件存储REST API 问题解决
问题1:实现读取JSON文件并转换为POJO列表
要完成DataLoaderService的convertJsonToPojo方法,需要先读取JSON文件内容,解析后提取指定节点的数组,再转换为对应POJO的列表。以下是完整实现:
1. 完善JsonFileService的文件读取逻辑
假设JSON文件放在classpath下的data/persons.json,先实现文件读取:
@Service public class JsonFileService { private final ResourceLoader resourceLoader; @Autowired public JsonFileService(ResourceLoader resourceLoader) { this.resourceLoader = resourceLoader; } public String readFile() throws IOException { Resource resource = resourceLoader.getResource("classpath:data/persons.json"); return Files.readString(resource.getFile().toPath()); } }
2. 实现convertJsonToPojo方法
在DataLoaderService中完成JSON转POJO列表的逻辑:
public <T> List<T> convertJsonToPojo(String nodeName, Class<T> classOfT) { try { String jsonContent = jsonFileService.readFile(); JsonNode rootNode = mapper.readTree(jsonContent); JsonNode targetNode = rootNode.get(nodeName); // 校验节点是否存在且为数组 if (targetNode == null || !targetNode.isArray()) { return Collections.emptyList(); } // 将数组节点转换为POJO列表 return mapper.readValue( targetNode.traverse(), mapper.getTypeFactory().constructCollectionType(List.class, classOfT) ); } catch (IOException e) { e.printStackTrace(); return Collections.emptyList(); } }
问题2:构造方法初始化场景下的Mockito测试解决方案
原测试失败的核心原因:
- 在
setUp中先创建了PersonRepository实例,此时构造方法立即调用loaderService.convertJsonToPojo,但mock的返回值还没设置,导致返回默认空列表。 - 原测试中mock的参数是小写的
"persons",但PersonRepository构造方法里传的是大写的"Persons",参数不匹配也会导致mock失效。
修正后的测试代码:
@ExtendWith(MockitoExtension.class) public class PersonRepositoryTest { PersonRepository repository; @Mock private DataLoaderService loaderService; @BeforeEach public void setUp() { // 1. 先准备模拟数据并设置mock返回值(注意匹配构造方法里的参数"Persons") List<Person> mockedList = Arrays.asList( new Person("Paul","Moes","1", "7777", "adresse tour", "Chicago", "pauln@gmail.com"), new Person("Eleson","Moc","2", "77777", "ddkdkd", "New York", "eleson@gmail.com") ); doReturn(mockedList).when(loaderService).convertJsonToPojo("Persons", Person.class); // 2. 再创建Repository实例,此时构造方法调用会拿到模拟的列表 repository = new PersonRepository(loaderService); } @Test public void getAllPersonnesInConstructor() { List<Person> persons = repository.getAll(); assertEquals(2, persons.size(), "Expected list size is 2"); assertEquals(persons, mockedList); } }
核心调整是先设置mock的返回逻辑,再初始化Repository,确保构造方法调用时mock已经准备好;同时修正了参数大小写不匹配的问题。
内容的提问来源于stack exchange,提问作者oligo oliogo
相关产品推荐
相关产品推荐

