[Novice] Problems with .expect and throwing Errors

1,324 views
Skip to first unread message

Charles Barkley

unread,
Jan 1, 2016, 9:58:47 AM1/1/16
to Mocha
Hello together!

I just found myself starting with TDD and Testing overall with Meteor.js and its Mocha Package.
While everything went fine just yet I began to slip when it comes to testing out throwing of errors.

I'd like to show you some tests for my helper methods. Please don't care about my newby code styles but more what I need to get solved: the chai.except part here.

if (Meteor.isClient) {

changeProfileName = function (newName) {

if (isEmptyOrBlankString(newName)) {
throw new TypeError('Profile name is blank or empty.');
}

var currentUserId = Meteor.user()._id;
Meteor.users.update({_id: currentUserId}, {$set: {'profile.name': newName}})
};

isEmptyOrBlankString = function (string) {
if (isString(string) == false) {
throw new TypeError('Parameter is not of type string.');
}
return _.isEmpty(string.trim());
};

isString = function (string) {
return typeof string === "string";
}
}

Here you can see that I have two errors being thrown. Now to the testing parts:

if (!(typeof MochaWeb === 'undefined')) {
MochaWeb.testOnly(function () {

describe("Client: Helper methods", function () {

describe(" isEmptyOrBlankString Method", function () {
var string = " ";
it("has a param which is an empty or whitespace only string - returns true", function () {
chai.assert.equal(isEmptyOrBlankString(string), true);
});
it("has a param which is not a string - throw TypeError", function () {
chai.expect(isEmptyOrBlankString).to.throw(/(?:\b(?:Parameter|type|string)\b.*){3}/);
});

});

describe(" isString Method", function () {
it("has a param which is a string - return true", function () {
chai.assert.equal(isString("text"), true);
});
it("has a param which is NOT a string (number) - returns false", function () {
chai.assert.equal(isString(123), false);
});
it("has a param which is NOT a string (object) - returns false", function () {
chai.assert.equal(isString({test : 'test'}), false);
});
});

//end
});
});
}

This test looks for a error thrown which has the message "Parameter is not of type string" and find it. so for this method there isnt an assertion problem. But:

if (!(typeof MochaWeb === 'undefined')) {
MochaWeb.testOnly(function () {

describe("Client: Profilechange methods", function () {
describe(" Login Testprofile", function () {
var loggedIn = false;
before(function () {
Meteor.loginWithPassword('testuser', 'test123');
loggedIn = Meteor.user() ? true : false ;
});
it("logged in with test account", function(){
chai.assert(Meteor.user(), true);
});
});

describe(" Change profile name (valid parameter)", function () {
before(function () {
changeProfileName('testname');
});
after(function(){
changeProfileName('testuser');
});
it("changed profile name", function(){
chai.assert.equal(Meteor.user().profile.name, 'testname');
});
});

describe(" Change profile name (invalid parameter)", function () {
it("throws error for empty or blank string param", function(){
chai.expect(changeProfileName).to.throw(/(?:\b(?:Profile|name|blank|empty)\b.*){4}/);
});
});

//end
});
})
}

This test receives a assertion error : expected [Function] to throw error matching /(?:\b(?:Profile|name|blank|empty)\b.*){4}/ but got 'Parameter is not of type string.'

The problem here is that within the changeProfileName function there is the isEmptyOrBlankString function which throws the expected error BUT: within the isEmptyOrBlankString is the isString function which ALSO throws an error. So this error will be thrown first before the "expected" error. This makes my test to fail and I have no idea how to prevent it to be thrown. I read about using ".and.not.throw(/good function/);" but it did not worked yet.


I would be very glad if you guys could help me out on that anyhow!


Greets Charlie!



Vlad GURDIGA

unread,
Jan 2, 2016, 8:21:34 AM1/2/16
to Mocha
Hey Charles! :)

Looking at the code, it seems reasonable to expect the “Parameter is not of type string” error.

Looking at isEmptyOrBlankString it looks like it has more than one responsibility. I think I would extract the value presence check into its own function, say isMissing. This would allow changeProfileName to have a specific check — and error — for the case when it’s called without a value. 8-)

I would give isMissing a try and see how it changes your code, and its testability.

Cheers!
Reply all
Reply to author
Forward
0 new messages