我在这个测试中遇到了问题,这个端点会挂起(也尝试了WebTestClient,它会抛出超时,所以这个问题与mock mvc无关),在返回被调用后,改变了一些配置,现在我得到了HttpMessageNotableException。
我几乎可以肯定它是处理模拟InputStreamResource类型的东西。
我已经创建了最小的设置来重现此错误。
下面是测试类:
import static org.mockito.Mockito.anyString;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import java.io.File;
import java.io.FileInputStream;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.msf.sits.health.mail.MailService;
import org.msf.sits.health.share.FileShareService;
import org.msf.sits.health.share.FileDownloadInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureWebMvc;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@AutoConfigureWebMvc
@ExtendWith(MockitoExtension.class)
public class FileDownloadControllerTest extends TestcontainersInitializer{
@MockBean
private MailService mailService;
@MockBean
private FileShareService fileShareService;
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Autowired
private MockMvc mockMvc;
@Autowired
private HttpMessageConverter[] httpMessageConverters;
@Autowired
private FilesDownloadController controller;
@BeforeEach
void setUp() {
this.mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setMessageConverters(httpMessageConverters).build();
}
@Test
@DisplayName("200 - GET /downloadz/{token}")
void downloadzFileTest() throws Exception {
var token = "GbdARtD594xVpQQqOHAg0cOQSvx5LKGD";
File testFile = new File("src/test/resources", "integration/mocked-file.txt");
InputStreamResource testInputStream = new InputStreamResource(new FileInputStream(
testFile));
when(fileShareService.getFileDownloadInfo(anyString(), anyString())).thenReturn(
new FileDownloadInfo("mocked-file.txt", testInputStream.contentLength(),
testInputStream)
);
MvcResult result = null;
try {
result = mockMvc.perform(MockMvcRequestBuilders
.get("/downloadz/{token}", token)
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.accept(MediaType.APPLICATION_OCTET_STREAM))
.andDo(print())
.andExpect(status().isOk()).andReturn();
} catch (Exception e) {
System.out.println("Exception: " + e.getMessage());
}
}
}
字符串
这里是控制器:
import jakarta.servlet.http.HttpServletRequest;
import lombok.RequiredArgsConstructor;
import org.msf.sits.health.share.FileShareService;
import org.msf.sits.health.share.MedicalFileDownloadInfo;
import org.springframework.core.io.InputStreamResource;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequiredArgsConstructor
public class FilesDownloadController {
private final FileShareService fileShareService;
@GetMapping("/downloadz/{token}")
public ResponseEntity<InputStreamResource> downloadFile(@PathVariable String token,
HttpServletRequest request) {
MedicalFileDownloadInfo medicalFileDownloadInfo = fileShareService.getMedicalFileDownloadInfo(
token, request.getRemoteAddr());
HttpHeaders headers = new HttpHeaders();
headers.add(HttpHeaders.CONTENT_DISPOSITION,
"attachment; filename=" + medicalFileDownloadInfo.getFileName());
var response = ResponseEntity.ok()
.headers(headers)
.contentLength(medicalFileDownloadInfo.getContentLength())
.contentType(MediaType.APPLICATION_OCTET_STREAM)
.body(medicalFileDownloadInfo.getContent());
return response;
}
}
型
POM.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>3.1.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.msf.sits</groupId>
<artifactId>health</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>health</name>
<description>health</description>
<properties>
<java.version>17</java.version>
<spring-cloud-azure.version>5.5.0</spring-cloud-azure.version>
<vaadin.version>24.1.7</vaadin.version>
<tikka.version>2.9.1</tikka.version>
<springdoc-openapi-starter-webmvc-ui.version>2.0.2</springdoc-openapi-starter-webmvc-ui.version>
<spring-boot.testcontainers.version>3.2.0-M3</spring-boot.testcontainers.version>
<testcontainers.version>1.19.3</testcontainers.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-oauth2-resource-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-active-directory</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-keyvault-secrets</artifactId>
</dependency>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-starter-storage-file-share</artifactId>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>com.sendgrid</groupId>
<artifactId>sendgrid-java</artifactId>
<version>4.9.3</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
<version>${springdoc-openapi-starter-webmvc-ui.version}</version>
</dependency>
<dependency>
<groupId>org.apache.tika</groupId>
<artifactId>tika-core</artifactId>
<version>${tikka.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<!-- test dependencies -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-inline</artifactId>
<version>5.2.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-testcontainers</artifactId>
<version>${spring-boot.testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter</artifactId>
<version>5.9.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>postgresql</artifactId>
<version>${testcontainers.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.testcontainers</groupId>
<artifactId>testcontainers</artifactId>
<version>1.19.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-core</artifactId>
<version>5.8.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-webflux</artifactId>
<scope>test</scope>
</dependency>
<!-- test dependencies -->
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.azure.spring</groupId>
<artifactId>spring-cloud-azure-dependencies</artifactId>
<version>${spring-cloud-azure.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-bom</artifactId>
<version>${vaadin.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
<plugin>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-webapp-maven-plugin</artifactId>
<version>2.12.0</version>
<configuration>
<schemaVersion>v2</schemaVersion>
<subscriptionId>${env.SUBSCRIPTION_ID}</subscriptionId>
<resourceGroup>${env.RESOURCE_GROUP}</resourceGroup>
<appName>${env.APP_NAME}</appName>
<pricingTier>${env.TIER}</pricingTier>
<region>${env.REGION}</region>
<runtime>
<os>Linux</os>
<javaVersion>Java 17</javaVersion>
<webContainer>Tomcat 10.0</webContainer>
</runtime>
<deployment>
<resources>
<resource>
<directory>${project.basedir}/target</directory>
<includes>
<include>*.war</include>
</includes>
</resource>
</resources>
</deployment>
</configuration>
</plugin>
</plugins>
</build>
<reporting>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jxr-plugin</artifactId>
<version>3.3.0</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-checkstyle-plugin</artifactId>
<version>3.3.0</version>
<configuration>
<configLocation>sun_checks.xml</configLocation>
</configuration>
<reportSets>
<reportSet>
<reports>
<report>checkstyle</report>
</reports>
</reportSet>
</reportSets>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-pmd-plugin</artifactId>
<version>3.21.0</version>
</plugin>
</plugins>
</reporting>
<profiles>
<profile>
<id>production</id>
<build>
<plugins>
<plugin>
<groupId>com.vaadin</groupId>
<artifactId>vaadin-maven-plugin</artifactId>
<version>${vaadin.version}</version>
<executions>
<execution>
<id>frontend</id>
<phase>compile</phase>
<goals>
<goal>prepare-frontend</goal>
<goal>build-frontend</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</profile>
</profiles>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
型
1条答案
按热度按时间v09wglhw1#
为了解决由流mock引起的无限挂起的问题,我必须以下面的方式模拟storageFileInputStream及其读取方法:
设置模拟的代码段:
字符串
使用
read()
mock实现的方法:型