Is there a way to extend the Frisby.js module with custom expect
methods? I don't want to modify the source code, these extensions are specific to my REST API. My goal is to avoid repeating common tests by combining them into a method.
The problem is that the Frisby.js module exports its methods with this code:
exports.create = function(msg) {
return new Frisby(msg);
};
How would I add new methods to Frisby? This is more of a Javascript inheritance question as it applies to Node.js modules.
For example, a script to test the StackExchange API would have a lot of duplicate .expect
clauses, like .expectHeader()
and .expectJSONTypes()
. I would like to combine these into a .expectSEwrapper()
method. This method is unique to the StackExchange API so it wouldn't belong in Frisby.js. The script would look like this:
var frisby = require('frisby');
frisby.create('StackOverflow Info')
.get('https://api.stackexchange.com/2.2/info?site=stackoverflow', {gzip: true})
.expectStatus(200)
.expectHeader('content-type', 'application/json; charset=utf-8')
.expectHeader('content-encoding', 'gzip')
.expectJSONTypes('', {
items: Array,
has_more: Boolean,
quota_max: Number,
quota_remaining: Number
})
.toss();
frisby.create('StackOverflow Badges')
.get('https://api.stackexchange.com/2.2/badges?order=desc&sort=rank&site=stackoverflow', {gzip: true})
.expectStatus(200)
.expectHeader('content-type', 'application/json; charset=utf-8')
.expectHeader('content-encoding', 'gzip')
.expectJSONTypes('', {
items: Array,
has_more: Boolean,
quota_max: Number,
quota_remaining: Number
})
.expectJSONTypes('items.0', {
badge_type: String,
award_count: Number,
rank: String,
badge_id: Number,
link: String,
name: String
})
.toss();
I would like to have the script look more like this:
frisby.create('StackOverflow Info')
.get('https://api.stackexchange.com/2.2/info?site=stackoverflow', {gzip: true})
.expectSEwrapper()
.toss();
frisby.create('StackOverflow Badges')
.get('https://api.stackexchange.com/2.2/badges?order=desc&sort=rank&site=stackoverflow', {gzip: true})
.expectSEwrapper()
.expectJSONTypes('items.0', {
badge_type: String,
award_count: Number,
rank: String,
badge_id: Number,
link: String,
name: String
})
.toss();
This would mean adding a new method that looks like this:
frisby.expectSEwrapper = function() {
return this.expectStatus(200)
.expectHeader('content-type', 'application/json; charset=utf-8')
.expectHeader('content-encoding', 'gzip')
.expectJSONTypes('', {
items: Array,
has_more: Boolean,
quota_max: Number,
quota_remaining: Number
});
But how do I add it to the Frisby prototype from inside of my script?
I came up with one solution that is basically a wrapper for Frisby.js. In a new Node module (which I called config.js
), it extends the create()
function:
var frisby = require('frisby');
// Customize Frisby.js for the StackExchange REST API
exports.frisby = {
create: function(describe) {
var _frisby = frisby.create(describe);
_frisby.expectSEwrapper = function() {
return this.expectStatus(200)
.expectHeader('content-type', 'application/json; charset=utf-8')
.expectHeader('content-encoding', 'gzip')
.expectJSONTypes('', {
items: Array,
has_more: Boolean,
quota_max: Number,
quota_remaining: Number
});
}
return _frisby;
}
}
Then, in my Frisby.js spec file, I require
this module:
var config = require('./config.js');
var frisby = config.frisby;
After this, I can write:
frisby.create('StackOverflow Info')
.get('https://api.stackexchange.com/2.2/info?site=stackoverflow', {gzip: true})
.expectSEwrapper()
.toss();