Jasmine test case error: spy error to have been called - javascript

I have the following code that needs to be tested in Jasmine
sampleMethod() {
if (this.sampleObject) {
// business logic
} else {
console.error('sampleObject not initialized');
}
}
I had referred to Spying on console.error() with Jasmine to add jasmine test to monitor console.error.
it('should check for console.error', () => {
spyOn(console, 'error');
component.sampleMethod();
expect(console.error).toHaveBeenCalled();
});
However, I'm getting the following error:
Error: Expected spy error to have been called.
SampleObject is undefined. I've also tried adding spyOn to beforeEach. Still, I'm getting the error.

Can you try this to ensure that sampleObject is undefined and try assigning the spy to a variable?
it('should check for console.error', () => {
const errorSpy = spyOn(console, 'error');
component.sampleObject = undefined;
component.sampleMethod();
expect(errorSpy).toHaveBeenCalled();
});

Related

Sinon Stub is not throwing an error when fs.readFileSynch also throws an error

After going through all related issues regarding stubbing readFile/Sync with Sinon /Chai/ Mocha, the test is failing.
There's a basic getFile function that retrieves a file:
function getFile(path) {
const file = fs.readFileSync(path, "utf8)
return file;
}
module.exports = {getFile}
and I want to create a test where getFile should throw an error if fs.readFileSync also throws an error:
it('should throw an error if fs.readFileSync throws an error', () => {
I tried:
it('should throw an error if fs.readFileSync throws an error', () => {
const error = new Error('some error message')
const myStub = sinon.stub(fs, "readFileSync")
myStub.throws(error)
const filePath = "/Project/test.js"
const gFile = index.getFile(filePath)
try {
if(myStub.error === true) {
gFile(error)
} catch (error) {
expect(myStub).to.throw(error)
What I got was:
1 failing
Error: some error message
at Context.
at process.processImmediate
See the chai expect docs on throw(). There is this example:
var badFn = function () { throw new TypeError('Illegal salmon!'); };
expect(badFn).to.throw();
You see that expect(badFn) gets badFn not badFn(), so nowhere in the test is badFn actually called.
This means that expect calls badFn. And actually, expect needs to be the one to call it because it needs to catch the error.
So in your code, try this:
const stub = sinon.stub(fs, 'readFileSync').throws();
const callGetFile = () => {
index.getFile('some_file');
};
expect(callGetFile).to.throw();
Try putting your error function in the Sinon throw method as below.
myStub.throws(new Error('some error message'));

how to test that a method rethrow existing error using chai and sinon

We have a method which takes as arguments a potential error triggered a level higher. We want to test
handleFailure((msg, err) => {
if (err) throw err // preserve stack
console.error(msg);
process.exit(1);
})
We want to test, in case there is an error, that the error is thrown. We tried this:
it('should throw error', () => {
let error = new Error('someError');
expect(handleFailure('some message', error)).to.throw(error);
});
The error is thrown, I can see it in console. But it's not "captured" by the unit test:
1 failing
1) command processor
handleFailure method
should throw error:
Error: someError
at Context.it (tests/commandProcessor.spec.js:111:39)
How can we test the error is thrown using sinon and chai?
The problem with your code is, expect is never called as the error is thrown before returning from handleFailure.
One way you can handle it is by wrapping your code in an anonymous function as below.
it('should throw error', () => {
let error = new Error('someError');
expect(function(){handleFailure('some message', error)}).to.throw(error);
});

Test error handling of async function with jasmine

I have the following async function:
async $onInit() {
try {
this.settings = await this.Service.getSettings(this.companyId);
} catch (error) {
this.uiFeedback.showSystemError('There was an error processing the request.', error);
}
}
I am trying to test if the function displays an error if the async function catches an error. At the moment the only spec which successfully managed to do this was the following:
it('should show error if api call to get availability settings fails', () => {
Company.getSettings = () => {
throw new Error();
};
try {
cmp.$onInit().catch(() => {});
}
catch (error) {
expect(uiFeedback.showSystemError).toHaveBeenCalled();
}
});
So basically i need to add two extra catch blocks within my test to get this test to work. Otherwise i get the following error:
ERROR: 'Unhandled promise rejection', 'error'
Is there a better way to do this?
So it turns out the issue is simply how karma handles errors for async functions. this.uiFeedback was undefined in the $onInit function. However karma did not show the uiFeedback is undefined error until i ran the tests in Chrome and checked the console there. Something for everyone to watch out for when testing async functions with karma jasmine.

Compare errors in Chai

I needed to implement my own error class in ES6 (with node v4):
class QueryObjectError {
constructor (message) {
this.message = message;
}
}
I have a portion of code that throws said error type:
function myFunct () {
throw new QueryObjectError('a message');
}
And I am using Mocha and Chai to test the the function throws the expected error with the expected message:
it('is a test', function (done) {
var err = new QueryObjectError('abc');
assert.throw(myFunct, err);
done();
});
The test passes although the QueryObjectError objects have different messages and I want to test the case in which deep equality is checked. Any way to solve this with the given tools?
There are two salient issues with your code:
You do not use assert.throw correctly. You should pass the constructor to the expected exception as the 2nd argument and a regular expression or a string as the 3rd argument. If the 3rd argument is a string, Chai will check that the string exist in the exception's message. If it is a regular expression, it will test whether the message is matched by the expression.
Your exception should have a toString method that returns the message, otherwise Chai won't know how to check the message.
Here is an example showing a failure and a success:
import { assert } from "chai";
class QueryObjectError {
constructor (message) {
this.message = message;
}
toString() {
return this.message;
}
}
function myFunct () {
throw new QueryObjectError('a message');
}
it('is a test', function () {
assert.throw(myFunct, QueryObjectError, 'abc');
});
it('is another test', function () {
assert.throw(myFunct, QueryObjectError, /^a message$/);
});

angular.js Assert error throw async

I'm testing an angular.js app using karma with sinon-chai. I need to test a code like this:
var sync = function() {
async.then(function() {
// success
}, function() {
throw Error('foo');
});
}
sync is the function I want to test. async is a function returning a $q promise I want to test it fails throwing an error.
My ideal test suit:
describe('unit', function() {
it('should throw an error', function() {
expect(function() {
return sync();
}).to.throw(Error, 'foo');
})
});
But, it fails at afterEach() because the error is thrown on $digest.
How can I achieve this test?
Thank you very much!

Categories