Reputation: 833
After a long search, I finally found swagger-test to be the best framework to test my REST services from a swagger spec. I followed the read me and the example in the Repo. This is my first xamples
request/response pair.
"x-amples": [{
"description": "should save an object",
"request": {
"params": {
"app_id": "bengi",
"table_name": "Student",
"body": {
"collectionName": "Student",
"key": "mLiJB380x9893rjlaf0"
}
}
},
"response": {
"status": 200,
"headers": {
"content-type": "application/json"
}
}}]
app_id
and table_name
are substituted very well in the url
.
My problem is that the parameter body
is never included in the http request. I know this because I have inspected the traffic from wireshark.
I am quite sure my specs are very okay because I have been running successful tests manually from Swagger-UI. Here is a screen shot of my console:
Meaning my request is unauthorised due to missing key
parameter which is in the request body
above.
This is my js.js file called by mocha
:
var swaggerTest = require('swagger-test');
var fs = require('fs');
var preq = require('preq');
var swaggerSpec;
var buffer = fs.readFileSync('cb.json');
swaggerSpec = JSON.parse(buffer);
var xamples = swaggerTest.parse(swaggerSpec);
describe('specification-driven tests', function () {
xamples.forEach(function (xample) {
it(xample.description, function() {
this.timeout(10000);
return preq[xample.request.method](xample.request)
.then(function (response) {
assert.deepEqual(response, xample.response);
});
});
});
});
What should I do to ensure that my request body
is seen and used by swagger-test
?
Upvotes: 2
Views: 1283
Reputation: 833
After several hours of crawling the web and getting no solution, I tried to go through the code and the modules used. This is what I found out that solved my problem:
My x-amples
JSON is wrongly formatted, especially where I have placed my body
element.
From my question
app_id
andtable_name
are substituted very well in the url.
Well that is because of this line:
var xamples = swaggerTest.parse(swaggerSpec);
from the test file
.
The main function of swagger-test Is to parse the Swagger specification file and extract all x-ample
elements into an array as demonstrated by this line:
var xamples = swaggerTest.parse(swaggerSpec);
This means swagger-test does its work perfectly i.e:
x-ample
extentions into an array.Substitute the values in params
element:
"request": {
"params": {
"app_id": "bengi",
"table_name": "Student",
"body": {
"collectionName": "Student",
"key": "mLiJB380x9893rjlaf0"
}
}
}
into the url
template:
e>/data/{app_id}/{table_name}
Concatenate the host
,basePath
and params
from the swagger-spec
and request
JSON to form a complete uri
.
All this is done in this code snippet which does the donkey work in
function parseXample(spec, uri, method, xample) {
var uriTemplate = template.parse(uri);
var expandedUri = uriTemplate.expand(xample.request.params);
xample.request.method = method;
xample.request.uri = spec.host + spec.basePath + expandedUri;
return {
description: xample.description || method + ' ' + uri,
request: xample.request,
response: xample.response
};
}
From my question:
My problem is that the parameter body is never included in the http request
The trick was in the preq module source code in the getOptions([url],[o],[method])
method.
if (o.body && o.body instanceof Object) {
if (o.headers && /^application\/json/.test(o.headers['content- type'])) {
o.body = JSON.stringify(o.body);
} else if (o.method === 'post') {
o.form = o.body;
o.body = undefined;
}
}
Argument o
is options
that is the xample.request
object passed to preq from my test code:
return preqxample.request.method
So it becomes clear that xample.request.body
was in existent in my request object since it is at xample.request.params.body
and consequently the condition if (o.body && o.body instanceof Object)
does not pass and hence the assignment o.body=JSON.stringify(o.body)
did not happen.
The final x-ample
extension should look like this:
"x-amples": [{
"description": "should save an object",
"request": {
"method": "put",
"uri": "/data/{app_id}/{table_name}",
"headers": {
"content-type": "application/json"
},
"body": {
"collectionName": "Student",
"key": "xxxxxx"
},
"params": {
"app_id": "xxxxxx",
"table_name": "xxxxxx"
}
},
"response": {
"status": 200,
"headers": {
"content-type": "application/json"
}
}
}]
Apart from the location of the body
element, you must include the headers
element, else you get an error.
Upvotes: 3