I am trying to use Sinon to test a JS component which looks a bit like this...
import Bootbox from "../helpers/bootbox";
import Guard from "../helpers/guard";
import UrlHelper from "../helpers/url-helper";
export default class DeleteButton {
/**
* Creates an instance of DeleteButton.
*
* @param {object} element The DOM element to make into a delete button.
*
* @memberOf DeleteButton
*/
constructor(element) {
Guard.throwIf(element, "element");
this.deleteUri = element.getAttribute("data-delete-uri") || UrlHelper.current.url().split('?')[0];
this.title = element.getAttribute("data-title") || `Delete the item?`;
this.cancelText = element.getAttribute("data-cancel") || `Cancel`;
this.confirmText = element.getAttribute("data-confirm") || `Remove`;
this.message = element.getAttribute("data-message") || `Do you want to delete the item? This cannot be undone.`;
this.successUri = element.getAttribute("data-success-uri");
this.errorMessage = element.getAttribute("data-error-message") || `Unable to complete operation.`;
}
/**
* Shows failure of deletion.
*
* @memberOf DeleteButton
*/
showFailed() {
Bootbox.alert({
message: this.errorMessage,
size: `small`,
backdrop: true
});
}
}
The test looks like this...
it("Can show a fail message", function() {
$("body").append(`<a class="js-delete-button" data-id="123" data-delete-uri="/delete/123">Delete</a>`);
let objUt = new DeleteButton($(".js-delete-button").get()[0]);
let bootboxAlertStub = Sinon.stub(Bootbox, 'alert');
objUt.showFailed();
let args = bootboxAlertStub.args;
expect(args.message).to.equal(objUt.errorMessage);
});
But I can't get past the line let bootboxAlertStub = Sinon.stub(Bootbox, 'alert');
because I get an error from Karma saying 'Should wrap property of object'. I've tried wrapping it up in a Sinon.test wrapper as well and using this.stub but the error the is even more obtuse.
I've been through the Sinon.JS docs and searched online but I'm stuck. The code works fine.
I have looked at this posting, which is similar - Stubbing a class method with Sinon.js but it's not quite the same.
Looking at the actual underlying bootbox JavaScript file I'm effectively trying to stub a method that looks a bit like this (cut down)...
exports.alert = function() {
// do something
};
The JS file then returns the exports at the end...
return exports;
Looking at some Github postings it seems that it may not be possible to stub these particular calls as the underlying calls are utility functions rather than object functions.
I have mitigated this (in a horrible way) by changing my Bootbox wrapper class as follows...
export default {
/**
* Generates an alert box.
*
* @param {any} options
*/
alert: function(options) {
window.bootbox.alert(options);
},
/**
* Generates a confirmation dialog.
*
* @param {any} options
*/
confirm: function(options) {
window.bootbox.confirm(options);
}
}
This solves one problem and introduces another. While I can now stub Bootbox, when stubbed I can't get the arguments....
(from the test)
let args = bootboxAlertStub.args;
This is frustrating - The arguments are passed as a complex argument so a 'calledWith' assertion isn't going to cut it.
Is there any way I can get the arguments for a stub?
bootboxAlertStub.getCall(0).args
? – EssaygetCall
is the "index" of the call;0
is the first call to your stub,1
is the second call, etc. – Essay