gpt4 book ai didi

java - Spring - validator 不会在集成测试中触发

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:51:49 26 4
gpt4 key购买 nike

问题

其实这是一种"follow-up" question .我为文件上传运行了 2 个集成测试,测试相应的 Controller 。不幸的是,在使用我的另一个问题的答案的解决方案之后,应该“失败”的第二个集成测试(因为文件的扩展名是“错误的”,因此 FileContainerValidator 应该拒绝该文件)并没有失败! validator 甚至不会被调用。

如何解决问题?


我的代码

文件上传 Controller

@Controller
public class FileUploadController {

private final FileStorageService fileStorageService;

FileContainerValidator fileContainerValidator;

@Autowired
public FileUploadController(FileStorageService FileStorageService) {
this.fileStorageService = FileStorageService;
}

@Autowired
public void setDefaultFileContainerValidator(FileContainerValidator validator) {
this.fileContainerValidator = validator;
}

@GetMapping("/upload")
public String showTestFileUploadForm(@ModelAttribute Mapping mapping, FileContainer fileContainer, Model model) {
String path = "ERROR";
try {
path = new ClassPathResource("data.csv").getFile().getPath();
} catch (IOException e) {
e.printStackTrace();
}

model.addAttribute("shortenedFile", new TableConstructor(path, mapping.getContentDelimiter()));
return "upload";
}

@PostMapping("/upload")
public String uploadFile(Model model, @Valid FileContainer fileContainer, BindingResult result) {
if (!result.hasErrors()) {
System.out.println("Fetching file");
fileStorageService.store(fileContainer);
//TODO: SUCCESS
model.addAttribute("success", true);
}

return "upload";
}

@InitBinder("fileContainer")
protected void initBinderFileContainer(WebDataBinder binder) {
binder.setValidator(fileContainerValidator);
}
}

文件上传集成测试

@RunWith(SpringRunner.class)
@WebMvcTest(FileUploadController.class)
public class FileUploadIntegrationTest {

@Autowired
private MockMvc mockMvc;

@MockBean
private FileStorageService fileStorageService;

@MockBean
private FileContainerValidator fileContainerValidator;

private MockMultipartFile correctFile =
new MockMultipartFile("file", "filename.xml", "text/plain", "some xml".getBytes());

private MockMultipartFile fileWithWrongExtension =
new MockMultipartFile("file", "filename.txt", "text/plain", "this is a wrong file!".getBytes());

private String testDestination = "/tmp";

//THIS ONE WORKS
@Test
public void uploadMultipartTestFile() throws Exception {
when(fileContainerValidator.supports(any(Class.class))).thenReturn(true);
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/upload")
.file(correctFile)
.param("destination", "/tmp"))
.andExpect(model().attribute("success", true));
}

//THIS ONE DOES NOT WORK
@Test
public void errorOnUploadFileWithWrongExtension() throws Exception {
when(fileContainerValidator.supports(any(Class.class))).thenReturn(true);
mockMvc.perform(MockMvcRequestBuilders.fileUpload("/upload")
.file(fileWithWrongExtension)
.param("destination", "/tmp"))
.andExpect(model().attributeHasFieldErrors("fileContainer.file"));
}
}

文件容器 validator

@Component
public class FileContainerValidator implements Validator {
public boolean supports(Class<?> clazz) {
return FileContainer.class.equals(clazz);
}

@Override
public void validate(Object obj, Errors errors) {
FileContainer fileContainer = (FileContainer) obj;
MultipartFile file = fileContainer.getFile();
String destination = fileContainer.getDestination();
if (file != null) {
if (file.getSize() == 0) {
errors.rejectValue("file", "missing.file", "The file must not be null or empty!");
}
if(file.getOriginalFilename().contains(".")) {
String extension = file.getOriginalFilename().split("\\.")[1];
if (!extension.equalsIgnoreCase("xml") && !extension.equalsIgnoreCase("csv")) {
errors.rejectValue("file", "extension.file", "The file had the wrong extension!");
}
} else {
errors.rejectValue("file", "extension.file", "The file had the wrong extension!");
}
} else {
errors.rejectValue("file", "missing.file", "The file must not be null or empty!");
}
if(destination != null && !destination.isEmpty()){
if(!destination.matches("([a-zA-Z]:)?(\\/[a-zA-Z0-9_.-]+)+\\/?"))
errors.rejectValue("destination", "wrong.destination", "The destination is given wrong");
} else {
errors.rejectValue("destination", "missing.destination", "The destination is missing");
}
}
}

表单(“upload.html”)

<!DOCTYPE html SYSTEM "http://www.thymeleaf.org/dtd/xhtml1-strict-thymeleaf-spring4-4.dtd">
<html xmlns:th="http://www.thymeleaf.org" lang="en" xmlns="http://www.w3.org/1999/xhtml">
<head th:include="head :: head (pagename='Upload File')"></head>

<body>

<div th:replace="fragments/nav :: nav">&copy; Static</div>
<div class="panel panel-default" id="welcome-panel">
<div class="panel-heading">
<h2>Upload File</h2>
</div>
<div class="panel-body">
<div class="alert alert-success" th:if="${success}">File successfully uploaded!</div>
<form method="POST" action="#" th:action="@{/upload}" th:object="${fileContainer}"
enctype="multipart/form-data">
<h4>Upload files here:</h4>
<label for="file" class="upload-drop-zone">
Just drag and drop files <br> or click to upload.
<input type="file" th:field="*{file}" id="file" style="display:none;"/>
</label>
<br><br>
<label for="destination">Destination:</label>
<input type="text" value="/tmp" id="destination" th:field="*{destination}"/>
<br>
<button class="btn btn-success convert-button btn-block" type="submit" name="upload" id="upload">Create
</button>
<div class="alert alert-danger" th:if="${#fields.hasErrors('file')}" th:errors="*{file}"></div>
<div class="alert alert-danger" th:if="${#fields.hasErrors('destination')}"
th:errors="*{destination}"></div>
</form>

</div>
</div>
</div>

</body>

</html>

最佳答案

您不再使用“真正的”FileContainerValidator

@MockBean
private FileContainerValidator fileContainerValidator;

这要求 Spring 创建您的 FileContainerValidator 的虚假版本。因此,将不再调用 FileContainerValidator 中的任何真实代码。

如果您使用:

@SpyBean
private FileContainerValidator fileContainerValidator;

它确实使用了真正的实现,但允许您模拟奇怪的方法。所以你对 fileContainerValidator.supports 方法的模拟应该仍然有效。

关于java - Spring - validator 不会在集成测试中触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41016228/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com