我正在开发一个有趣的项目,其中包含一些随机人员数据(来自java-faker),以了解有关 java、spring、api、thymeleaf、软件测试的更多信息...
-> 来自 gitlab 的我的项目 除了许多小问题之外,junit、spring、mockmvc 的软件测试正在运行,但无法正常工作。带有分支junit-test-and-post-request
的代码将使用 mockmvc
连接到 api 和控制器,但生成的 json 响应为空。
我尝试并复制了其他人的许多其他解决方案和想法,他们用或多或少相似的代码展示了他们的方法,但所有这些都不适合我:(也许某个地方使用了错误的注释或错误的库版本。
带有测试代码的文件内容(请忽略嵌套类):
package com.example.demo;
import com.example.demo.controller.PersonController;
import com.example.demo.service.PersonService;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.test.context.event.annotation.AfterTestClass;
import org.springframework.test.context.event.annotation.BeforeTestClass;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.web.bind.annotation.ResponseBody;
import java.io.IOException;
import java.net.URI;
import java.net.URL;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
//@ExtendWith(SpringExtension.class)
//@WebMvcTest(PersonController.class)
@AutoConfigureMockMvc
@SpringBootTest
public class PersonTest {
@Autowired
private MockMvc mockMvc;
@Autowired
private PersonService personService;
@MockBean
private PersonController personController;
static final String url = "http://localhost:8000";
static final String urlCreateData = "http://localhost:8000/createMoreData?username=admin&pw=secret";
private static final Logger log = LoggerFactory.getLogger(PersonTest.class);
@Test
@ResponseBody
@DisplayName("1st lvl: basic request, get status http.ok")
public void testRequest() throws Exception {
log.info("1st lvl: basic request, get status http.ok");
mockMvc.perform(MockMvcRequestBuilders
.get(url)
.accept(MediaType.APPLICATION_JSON))
//.andDo(MockMvcResultHandlers.print())
.andExpect(MockMvcResultMatchers.status().isOk())
;
createWebsiteData();
}
private void createWebsiteData() throws Exception {
log.info("Create data with db:");
mockMvc.perform(MockMvcRequestBuilders
.post(urlCreateData)
.accept(MediaType.APPLICATION_JSON))
.andDo(MockMvcResultHandlers.print());
}
@Test
@ResponseBody
@DisplayName("Next lvl: basic request, get status http.ok, get json response with data path.")
public void testRequestWithJson() throws Exception {
log.info("Next lvl: basic request, get status http.ok, get json response with data path.");
log.info("Result:");
MvcResult mvcResult = mockMvc.perform(MockMvcRequestBuilders
.get(url)
.accept(MediaType.APPLICATION_JSON)
.characterEncoding("utf-8"))
.andExpect(MockMvcResultMatchers.status().isOk())
.andExpect(MockMvcResultMatchers.jsonPath("$."+personService.NAME_FOR_MODEL_DATA).exists())
.andReturn();
}
@AfterTestClass
@DisplayName("End -> Clean")
public void clean() {
log.info("End -> Clean");
}
@Nested
class Start {
@Test
@DisplayName("Next lvl -> tell program to create data")
public void testCallMethod(){
log.info("Next lvl -> tell program to create data");
}
@Test
@DisplayName("PersonTest Json:model exists")
public void testJsonPersonsExist() {
log.info("PersonTest Json:model exists");
}
@Nested
class IfExists {
@Test
@DisplayName("PersonTest Json:model is an array & is not empty")
public void TestJsonPersonsListIsNotEmpty() {
log.info("PersonTest Json:model is an array & is not empty");
}
@Test
@DisplayName("PersonTest Json:abc does not exist")
public void TestJsonWrongPersonsDoNotExist() {
log.info("PersonTest Json:abc does not exist");
}
@Test
@DisplayName("Test1 Json:abc does not exist")
public void TestJsonWrongPersonsDoNotExist1() {
log.info("PersonTest Json:abc does not exist");
}
@Test
@DisplayName("PersonTest Json:model[].id exists")
public void TestJsonPersonsIdExist() {
log.info("PersonTest Json:model[].id exists");
}
}
}
}
控制器文件内容:
package com.example.demo.controller;
import com.example.demo.entity.Person;
import com.example.demo.repository.PersonRepository;
import com.example.demo.service.PersonService;
import jakarta.servlet.http.HttpServletResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
import static com.example.demo.service.PersonService.*;
@RestController
//@Controller
//@RestController
//@RequestMapping("/index.html")
//@RequestMapping("/")
@RequestMapping("")
public class PersonController {
private static final Logger log = LoggerFactory.getLogger(PersonController.class);
@Autowired
Environment environment;
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
PersonRepository personRepository;
@Autowired
PersonService personService;
final String htmlFile = "index";
@PostMapping("/createMoreData")
@ResponseStatus(code = HttpStatus.OK)
public String createMoreData(
@RequestParam(required = false) String username,
@RequestParam(required = false) String pw,
Model model,
HttpServletResponse httpServletResponse){
switch (isAdminAccount(username, pw)) {
case YES -> {
if(isDatabaseEmpty()) {
createNewData(true);
model.addAttribute("message",
"Created new data with admin account(s).");
} else {
createNewData();
model.addAttribute("message",
"Created new data.");
}
model.addAttribute(personService.NAME_FOR_MODEL_DATA, getDataWithoutSensibleInfos(true, personRepository.findAll()));
model.addAttribute(personService.NAME_FOR_MODEL_PERMISSION, true);
}
case EMPTY_PARAMETER -> {
log.error(PersonService.IsAdmin.EMPTY_PARAMETER.toString());
model.addAttribute(personService.NAME_FOR_MODEL_MESSAGE,
"Did not create new data: " + PersonService.IsAdmin.EMPTY_PARAMETER.toString());
httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
model.addAttribute(personService.NAME_FOR_MODEL_DATA, getDataWithoutSensibleInfos(false, personRepository.findAll()));
model.addAttribute(personService.NAME_FOR_MODEL_PERMISSION, false);
}
case WRONG_PARAMETER -> {
log.error(PersonService.IsAdmin.WRONG_PARAMETER.toString());
model.addAttribute(personService.NAME_FOR_MODEL_MESSAGE,
"Did not create new data: " + PersonService.IsAdmin.WRONG_PARAMETER.toString());
httpServletResponse.setStatus(HttpServletResponse.SC_BAD_REQUEST);
model.addAttribute(personService.NAME_FOR_MODEL_DATA, getDataWithoutSensibleInfos(false, personRepository.findAll()));
model.addAttribute(personService.NAME_FOR_MODEL_PERMISSION, false);
}
}
return htmlFile;
}
@GetMapping("")
public String loadData(@RequestParam(required = false) String username, @RequestParam(required = false) String pw, Model model){
if(personService.CREATE_DB_DATA_ON_STARTUP && isDatabaseEmpty()) {
createNewData(true);
model.addAttribute(personService.NAME_FOR_MODEL_MESSAGE,
"Created new data with admin account(s).");
}
switch (isAdminAccount(username, pw)) {
case YES -> {
log.info(IsAdmin.YES.toString());
model.addAttribute(personService.NAME_FOR_MODEL_DATA, getDataWithoutSensibleInfos(true, personRepository.findByIsAdminTrue()));
}
case EMPTY_PARAMETER -> {
log.error(IsAdmin.EMPTY_PARAMETER.toString());
model.addAttribute(personService.NAME_FOR_MODEL_PERMISSION, false);
model.addAttribute(personService.NAME_FOR_MODEL_MESSAGE, IsAdmin.EMPTY_PARAMETER.toString());
model.addAttribute(personService.NAME_FOR_MODEL_DATA, getDataWithoutSensibleInfos(false, personRepository.findByIsAdminFalse()));
}
case WRONG_PARAMETER -> {
log.error(IsAdmin.WRONG_PARAMETER.toString());
model.addAttribute(personService.NAME_FOR_MODEL_PERMISSION, false);
model.addAttribute(personService.NAME_FOR_MODEL_MESSAGE, IsAdmin.WRONG_PARAMETER.toString());
model.addAttribute(personService.NAME_FOR_MODEL_DATA, getDataWithoutSensibleInfos(false, personRepository.findByIsAdminFalse()));
}
}
//model.addAttribute("Person", viewPerson);
return htmlFile;
}
private void createNewDataIfNotCreated(){
if(isDatabaseEmpty()){
List<Person> personList = createNewDataWithAdmin();
log.info("Saving all "+personList.size()+" data to database.");
personRepository.saveAll(personList);
}
}
private void createNewData(){
createNewData(false);
}
private void createNewData(boolean withAdmin){
List<Person> personList = null;
if(withAdmin) {
personList = createNewDataWithAdmin();
} else {
personList = PersonService.createNewData();
}
log.info("Saving all " + personList.size() + " data to database.");
personRepository.saveAll(personList);
}
private boolean isDatabaseEmpty(){
return jdbcTemplate.queryForList("select * from " + personService.DATABASE_NAME + " limit 1;").isEmpty();
}
}
错误消息如:注入库错误、缺少模板、jdbctemplate 位于错误的类中等等。 任何帮助,将不胜感激。 预先感谢。
您定义的测试具有
@SpringBootTest
。由于您没有设置更多配置详细信息,因此 URL 可用性使用默认值。
来自文档:
适用时要创建的 Web 环境类型。默认为 WebEnvironment.MOCK。
Mock 表示没有设置 URL 可用性。