今回は、HttpClient
を使ってテストを行うときに、本物の画像ファイルを用意しないでMultiPartData
を送信する方法について紹介します。
まず最初に、Ktorに画像や動画を送信するとき、Ktor側ではcall.receiveMultipart()
を使って、MultiPartData
を受け取ると思われます。
このとき、MultiPartData
インスタンスの中multipart data streamを表しています。
Kotlinでは、1つ以上のPartData
によってMultiPartData
が構成されています。このPartData
の種類には、PartData.FormItem
やPartData.FileItem
などがあります。これらは、MultiPartData
に対してforEachPart
を使うことで、順番に取り出すことができます。
multipart.forEachPart { partData ->
when(partData){
is PartData.FormItem -> {
// ...
}
is PartData.FileItem -> {
// ...
}
is PartData.BinaryItem -> {
// ...
}
is PartData.BinaryChannelItem -> {
// ...
}
}
}
それでは本題です。PartData.FileItem
を使って、テストコードから画像を送信する方法を紹介しますが、テストのためだけに画像ファイルを用意する必要があるのでしょうか?
それはとても大変であり、面倒なことだと思います。
ではどのようにして画像を送ったことを表現すれば良いのでしょうか?
ここで答えを言ってしまうと、byteArrayOf()
を使うことで、画像というよりは画像データを送ったことをテストの中で表現することができます。
val response = client.post("/post") {
setBody(MultiPartFormDataContent(
formData {
append("text", "こんにちわ")
append("image", byteArrayOf(1, 2, 3), Headers.build {
append("Content-Type", "image/jpeg")
append("Content-Disposition", "form-data; name=\"image\"; filename=\"image.jpg\"")
})
},
))
header("Authorization", "Bearer $token")
}
この時、一番大事なのはContent-Disposition
の部分です。これを設定することで、PartData.FileItem
として受け取ることができます。
余談ですが、append("Content-Type", "image/jpeg")
を指定しなくても、PartData.FileItem
として受け取ることができます。