使用Spring WebTestClient发送多部分表单数据

(x-posted from personal blog here)

Background

在过去的一年左右的时间里,我一直在大量研究spring,尤其是spring webflux。 为我们的客户构建可扩展的反应微服务。

Coming from spring MVC, learning webflux and getting used to reactive programming in general has been a great and worthy learning experience and I highly suggest going through the references section if you haven’t heard of reactive programming and/or have been thinking about giving it a go and don’t know where to start. But essentially reactive programming involves a model of creating, requesting and manipulating data in a controllable (from a consumers perspective) and non-blocking manner.

w ^ebTestClient is a reactive testing high level http client with fluent assertions, packaged in spring web flux. Recently, while integration testing an application that accepted data as multipart/form-data I had to figure out how to test the data effectively using the webtestclient and personally found the lack of comprehensive resources on the internet lacking, so I wrote this blogpost to share my own learnings.

Web Form Testing with Webflux

假设我们正在尝试发送请求以填充一个表单api的请求,该表单api接受文档(图像,文本,纯二进制等)和一些文本数据。

为了帮助我们的示例,假设表单是文档共享服务的配置文件设置,并接受以下输入:

  • 个人资料图片(api标签:profileImage)用户名 (api标签:用户名)电邮(api标签:电子邮件)PDF文件共享(api标签:userDocument)

For us to begin sending the data, we’ll use the spring library called MultipartBodyBuilder which provides a nice api for setting up the body for multipart requests.

要发送第一部分,我们可以将个人资料图像设置为:

val bodyBuilder = MultipartBodyBuilder()

bodyBuilder.part("profileImage", ClassPathResource("test-image.jpg").file.readBytes()).header("Content-Disposition", "form-data; name=profileImage; filename=profile-image.jpg")

To explain a bit about what’s going on there, we’re simply telling the body builder to upload an image found in src/test/resources folder with the name test-image.jpg as the profile image part of this body. The real kicker here is setting up the Header part as that is what’s used by the webtestclient internals (specifically the Synchronoss-nio library which webflux uses internally) to determine the type of form data being sent and how to process it.

另外,请注意,将在接收请求的Web服务器中上载的真实文件名是profile-image.jpg作为标题的一部分发送的文件名。

类似于个人资料图片,我们还可以发送整个请求有效内容的文档部分:

bodyBuilder.part("userDocument", ClassPathResource("user-document.pdf").file.readBytes()).header("Content-Disposition", "form-data; name=userDocument; filename=my-thesis.pdf")

与之前的有效负载类似,我们测试主体构建器💪以读取测试资源文件夹中的文件用户文档.pdf以字节为单位,并发送带有名称的文档我的论文.pdf到表单Web API。

As you can already see, compared to some other ways of doing it, such as in this excellent blog , using the MultipartBodyBuilder is rather conveneient.

现在,对于api表单的最后两个部分(通常只是纯文本),我们可以将它们设置为:

bodyBuilder.part("username", "shiveenpandita", MediaType.TEXT_PLAIN).header("Content-Disposition", "form-data; name=username").header("Content-type", "text/plain")

bodyBuilder.part("email", "shiveenpandita@gmail.com", MediaType.TEXT_PLAIN).header("Content-Disposition", "form-data; name=email").header("Content-type", "text/plain")

oo! now现在,我们已将所有表单字段连接起来。

现在,要查看所有功能并将它们整合在一起,我们可以简单地设置弹簧集成测试并将新设置的body builder用于:

@RunWith(SpringRunner::class.java)
@SpringBootTest
@AutoConfigureWebTestClient
class WebClientTest {

    private lateinit var webclient: WebTestClient

    @Test
    fun `test webform api`() {
        val bodyBuilder = MultipartBodyBuilder()

        bodyBuilder.part("profileImage", ClassPathResource("test-image.jpg").file.readBytes()).header("Content-Disposition", "form-data; name=profileImage; filename=profile-image.jpg")

        bodyBuilder.part("userDocument", ClassPathResource("test-document.pdf").file.readBytes()).header("Content-Disposition", "form-data; name=userDocument; filename=my-thesis.pdf")

        bodyBuilder.part("username", "shiveenpandita", MediaType.TEXT_PLAIN).header("Content-Disposition", "form-data; name=username").header("Content-type", "text/plain")

        bodyBuilder.part("email", "shiveenpandita@gmail.com", MediaType.TEXT_PLAIN).header("Content-Disposition", "form-data; name=email").header("Content-type", "text/plain")

        webClient.post()
            .uri("/v1/test-api")
            .contentType(MediaType.MULTIPART_FORM_DATA)
            .body(BodyInserters.fromMultipartData(bodyBuilder.build()))
            .exchange()
            .expectStatus().isOk
    }
}

上面的代码段将成功将所需的数据发送到我们的测试api,并且webtestclient断言响应为200 OK。

References

from: https://dev.to//shavz/sending-multipart-form-data-using-spring-webtestclient-2gb7

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值