测试 Spring 控制器时出现 EmptyResultDataAccessException

EmptyResultDataAccessException when testing Spring controller

在我的应用程序中,有一个控制器、一个服务、一个存储库和一个 class。我正在编写单元测试来验证我的 PUT 请求。在 postman 中,put 请求工作正常,但是,在 JUnit 测试中测试时,它会抛出 EmptyResultDataAccessException 错误。许多其他测试也有同样的问题,它们都需要通过 id 在 repo 中找到特定的条目。我认为这是问题所在。请帮我解决这个问题。

@Data
@Entity
public class ErrorMessage {
    private @Id @GeneratedValue Long id;
    private String message;
    private int code;

    public ErrorMessage() {
    }

    public ErrorMessage(int code, String message) {
        this.code = code;
        this.message = message;
    }
}
@Repository
interface ErrorMessageRepository extends JpaRepository<ErrorMessage, Long> {
    List<ErrorMessage> findByCode(int code);
}
@Service
public class ErrorMessageService {

    @Autowired
    ErrorMessageRepository repository;

    @Transactional  
    public List<ErrorMessage> getAll()
    {   
        return repository.findAll();
    }

    @Transactional(readOnly = true) 
    public Optional<ErrorMessage> getById(Long id)
    {   
        return repository.findById(id);
    }

    @Transactional(readOnly = true) 
    public List<ErrorMessage> getByCode(int code)
    {   
        return repository.findByCode(code);
    }

    @Transactional  
    public ErrorMessage saveOne(ErrorMessage messages)
    {   
        return repository.save(messages);
    }

    @Transactional  
    public Optional<ErrorMessage> deleteById(long id)
    {   
        Optional<ErrorMessage> em = repository.findById(id);
        repository.deleteById(id);
        return em;
    }

    @Transactional  
    public ErrorMessage updateById(long id, ErrorMessage newMessage)
    {   
        ErrorMessage m = repository.findById(id).get(); 
        m.setCode(newMessage.getCode());
        m.setMessage(newMessage.getMessage());
        repository.save(m);
        return m;
    }
}

class ErrorMessageController {
    private static final Logger log = LoggerFactory.getLogger(ErrorMessageController.class);

    @Autowired
    ErrorMessageRepository repository;

    @Autowired
    private ErrorMessageService ems;

    @GetMapping("/errormessages")
    public List<ErrorMessage> getAll() {
        return ems.getAll();
    }

    @GetMapping("/errormessagesbycode/{code}")
    public List<ErrorMessage> getByCode(@PathVariable int code) {
        return ems.getByCode(code);
    }

    @GetMapping("/errormessage/{id}")
    ErrorMessage getById(@PathVariable Long id) {
        return ems.getById(id)
                .orElseThrow(() -> new MessageNotFoundException(id));
    }

    @PostMapping("/errormessage")
    ErrorMessage newMessage(@RequestBody ErrorMessage newMessage) {
        return ems.saveOne(newMessage);
    }

    @DeleteMapping("/errormessage/{id}")
    Optional<ErrorMessage> deleteMessage(@PathVariable Long id) {
            return ems.deleteById(id);
    }

    @PutMapping("/errormessage/{id}")
    ErrorMessage updateMessage(@PathVariable Long id, @RequestBody ErrorMessage newMessage) {
        return ems.updateById(id, newMessage);
    }

}

@SpringBootTest
@AutoConfigureMockMvc
public class ErrorMessageTest {

    private static ErrorMessage em, emId;
    private static ObjectMapper mapper;

    @Autowired
    private MockMvc mockMvc;

    @BeforeAll
    public static void init() throws Exception {
        mapper = new ObjectMapper();
        em = new ErrorMessage(400, "bad request0");
        emId = new ErrorMessage(400, "bad request0");
        emId.setId(Long.valueOf(1));
    }

    @Test
    void putMessage() throws Exception {
        ErrorMessage modifiedMessage = new ErrorMessage(400, "modified");
        this.mockMvc.perform(MockMvcRequestBuilders
                    .put("/errormessage/{id}", emId.getId())
                    .contentType(MediaType.APPLICATION_JSON)
                    .content(mapper.writeValueAsString(modifiedMessage)))
                    .andExpect(status().isOk())
                    .andExpect(content().string(mapper.writeValueAsString(modifiedMessage)));
    }
}

试试这个

@Test
void putMessage() throws Exception {

    ErrorMessage modifiedMessage = new ErrorMessage(400, "modified");

    ErrorMessageService errorMessageService = Mockito.mock(ErrorMessageService.class);
    Mockito.when(errorMessageService.updateById(Mockito.any(), Mockito.any())).thenReturn(modifiedMessage);


    this.mockMvc.perform(MockMvcRequestBuilders
                .put("/errormessage/{id}", emId.getId())
                .contentType(MediaType.APPLICATION_JSON)
                .content(mapper.writeValueAsString(modifiedMessage)))
                .andExpect(status().isOk())
                .andExpect(content().string(mapper.writeValueAsString(modifiedMessage)));
}

我发现了错误。单元测试的顺序是随机的。我需要做的就是使用@Order 来确保顺序。