Reputation: 95
I am using Karate version 1.3.1 for our projects. Currently we have a use case to test an API which is taking a file and a metadata as part of the request.
we are using multipart file and field to write our feature file, but it seems when we check the POsT call on report we don’t see the metadata which is a Json going as part of the request.
As per the suggestion in link: https://github.com/karatelabs/karate/issues/1710
we tried the other approach to use multipart file and value as a parameter but it did not work for us.
Is there any other way to implement this on karate?
note: postman is working without any issues and we get a response too
please help if anyone has faced or resolved this.
Below is my feature file:
def temp = { 'upload': ['name':'test', 'org':123, 'branch': 'xyz', 'amount': 100], 'info': 8900, 'id': 123}
Given url "http://11.111.1.111:1111"
And path "/api/v1/upload
header Content-Type = 'multipart/form-data'
And multipart file file = {read: 'classpath:resources/file/file1.txt', filename: 'file1.txt'}
And multipart file metadata = {value: '#(temp)}
And method POST
print response
Note: I also tried * multipart field metadata = temp (but no luck here)
Response:
content-disposition: form-data; name= file; filename="file1.txt"
content-type: text/plain; charset= UTF-8
content-length: 5300
Completed: true
IsInMemory: true
content-disposition: form-data; name= metadata; filename=""
content-type: application/json; charset= UTF-8
content-length: 100
Completed: true
IsInMemory: true
The issue is when I run the feature file on Karate the api returns me 200 with a blank response. Response: { }
but when the same is executed from Postman it returns me response Response from postman: {id:123, status: ‘Done’}
also I tried the same request with Java okhttpClient request and it worked fine and gave me the expected response.
Implementation of Java Class for OkHttpClient (WORKING):
import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.util.Map;
public class OkHttpHelper {
private OkHttpClient client;
public OkHttpHelper() {
client = new OkHttpClient();
}
public String executeMultipartRequest(String url, Map<String, String> fields, Map<String, String> files) throws IOException {
MultipartBody.Builder requestBodyBuilder = new MultipartBody.Builder().setType(MultipartBody.FORM);
// Add fields
if (fields != null) {
for (Map.Entry<String, String> field : fields.entrySet()) {
requestBodyBuilder.addFormDataPart(field.getKey(), null, RequestBody.create(MediaType.parse("application/json"), field.getValue()));
}
}
// Add files
if (files != null) {
for (Map.Entry<String, String> file : files.entrySet()) {
File uploadFile = new File(file.getValue());
requestBodyBuilder.addFormDataPart(file.getKey(), uploadFile.getName(),
RequestBody.create(MediaType.parse("text/plain"), uploadFile));
}
}
RequestBody requestBody = requestBodyBuilder.build();
// Print requestBody content
System.out.println("Request Body: " + requestBodyToString(requestBody));
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
try (Response response = client.newCall(request).execute()) {
return response.body().string();
}
}
private String requestBodyToString(RequestBody requestBody) throws IOException {
Buffer buffer = new Buffer();
requestBody.writeTo(buffer);
return buffer.readUtf8();
}
}
Feature file looks like below:
Feature: Multipart Request with OkHttp
Background:
* def OkHttpHelper = Java.type('com.example.OkHttpHelper')
* def okHttpHelper = new OkHttpHelper()
Scenario: Send Multipart Request
* def url = 'https://example.com/upload'
And def fields = { "metadata": '{"key1": "value1"}' }
And def files = { "file": "path/to/file1.txt" }
When def response = okHttpHelper.executeMultipartRequest(url, fields, files)
Then print response
** CURL Command from POSTMAN**
curl -X POST \
http://11.111.11.111:1111/api/v1/fileupload
-H 'Accept: */*' \
-H 'Accept-Encoding: gzip, deflate' \
-H 'Cache-Control: no-cache' \
-H 'Connection: keep-alive' \
-H 'Content-Length: 5800' \
-H 'Content-Type: multipart/form-data; boundary=---------23434234234343' \
-H 'Host: 11.111.11.111:1111' \
-H 'Postman-Token: XXXXXX-xxxx-xxxx-xxxx-Xxxxxxx,XXXXXXXX' \
-H 'User-Agent: PostmanRuntime/X.XX.X' \
-H 'cache-control: no-cache' \
-H 'content-type: multipart/form-data; boundary=---------23434234234343' \
-F file@/C:/Test/Sample/file1.txt \
-F ‘metadata’= { "metadata": '{"key1": "value1"}' }
Upvotes: 1
Views: 838
Reputation: 58088
As far as I can tell, this should work:
* url 'https://httpbin.org/anything'
* multipart file file = { read: 'myfile.txt' }
* multipart field metadata = { some: 'data' }
* method post
You can experiment by pointing your okhttp or postman test to https://httpbin.org/anything
and see what are the differences. The response will tell you all the field values and file values sent in the request.
Upvotes: 0