Jasmine - Two spies for the same method - javascript

I'm new to Jasmine and I wanted to know if we can create 2 spies for the same method. Here is what I'm trying.
describe('something', function () {
beforeEach(function () {
mySpy = jasmine.createSpyObj('mySpy', 'functionInInterest');
mySpy.functionInInterest.andCallFake(function (cb) {cb(something);});
}
//Some Test Cases
describe('Here is the action!', function () {
mySpy = jasmine.createSpyObj('mySpy', 'functionInInterest');
mySpy.functionInInterest.andCallFake(function (cb) {cb(somethingElse);});
//Some test cases that depends on somethingElse
});
});
Testcases before Here is the action! depend on mySpy.functionInInterest.andCallFake(function (cb) {cb(something);}); where as test cases inside Here is the action! depend on mySpy.functionInInterest.andCallFake(function (cb) {cb(somethingElse);});
Note: Both have the same name
How can I achieve this? Thanks in advance!

instead of
describe('Here is the action!', function () {
mySpy = jasmine.createSpyObj('mySpy', 'functionInInterest');
mySpy.functionInInterest.andCallFake(function (cb) {cb(somethingElse);});
//Some test cases that depends on somethingElse
});
do this
describe('Here is the action!', function () {
mySpy_2 = jasmine.createSpyObj('mySpy', 'functionInInterest');
mySpy_2.functionInInterest.andCallFake(function (cb) {cb(somethingElse);});
//Some test cases that depends on somethingElse
});

Related

How can I use “do while” in mocha testing

For example, I have:
function test1() {
it("Test 1", function (done) {
...
});
}
function test2() {
it("Test 2", function (done) {
...
});
}
describe("main()", function () {
do {
test1();
test2();
} while (resultReturnBool);
});
Although resultReturnBool is "true", it does not redo test1 and test2.
What am I doing wrong? Am I using do-while correctly?
The do...while seems correct, maybe because of the way Mocha works it doesn't accept doing this kind of thing, have you seen any test using do...while? (just a question, i'm new to testing and i'm learning jest).
Try doing a normal while.
while(resultReturnBool) {
it('Test1', () => {
// Yout test here
});
it('Test2', () => {
// Yout test here
});
}

Unit testing jQuery getJSON function errors with the fail method, using Jasmine and Karma

I've written a unit test for a function that calls the jQuery getJSON method. The only thing that I'm testing is that it is called with the expected URL. My unit test uses a Jasmine Spy to mock the API call. However, when I run my unit tests I get this error:
1) should make a request to the expected URL when running on localhost
test module getDataFromApi function
TypeError: Cannot read property 'fail' of undefined
In my unit test I've created a Jasmine Spy, which returns the done and fail methods. What am I doing wrong here?
Here is my unit test:
describe('getFundDataFromApi function', function () {
beforeEach(function () {
spyOn($, "getJSON").and.callFake(function () {
return {
done: function () {},
fail: function () {}
};
});
});
it('should make a request to the expected URL when running on localhost', function () {
var expectedUrl = '/assets/mock-data/mock-data.json';
module.getDataFromApi();
expect($.getJSON).toHaveBeenCalled();
expect($.getJSON).toHaveBeenCalledWith({url:expectedUrl});
});
});
Function I'm trying to test: getDataFromApi
getDataFromApi: function () {
var mod = this;
var url = this.settings.apiUrl;
$.getJSON({
url: url
})
.done(function (data) {
mod.processApiData(data);
})
.fail(function () {
mod.displayErrorMessage();
});
},
In your function getDataFromApi you are chaining the call of fail after done but, in the mocked version of done, it returns nothing(undefined), so, you get TypeError: Cannot read property 'fail' of undefined.
You can make the done function to return an object with a fail property that is a function.
beforeEach(function() {
spyOn($, "getJSON").and.callFake(function() {
return {
done: function() {
return { fail: function() {} };
}
};
});
});
Or, one line ES6 version
spyOn($, "getJSON").and.callFake(() => ({ done: () => ({fail: () => {}}) }));
Or, if you are planning to do more in your tests, like testing success or failed responses, probably returning a jQuery Deferred can help you
beforeEach(function() {
spyOn($, "getJSON").and.callFake(function() {
const deferred = $.Deferred();
deferred.resolve({'success': true});
return deferred;
});
});
Calling deferred.reject({'success': false}); will give you the chance to test for errors.
Hope it helps

Jasmine test a callback passed to an anonym function

Hellow,
I have something like
export class Api {
callHttpClient(url, options, settings) {
this.httpClient.configure(callbackObjectInstance => {
callbackObjectInstance.method();
}); // And then some code
}
}
How could I spyOn the callbackObject.method with Jasmine test framework ?
Thank you
This should work as one approach.
describe('Given the API', function(){
let api;
let callback;
beforeEach(function(){
api = new Api();
callback = {
method: function() { }
};
spyOn(callback, 'method');
spyOn(api.httpClient, 'configure').and.returnValue(callback);
});
it('should call method', function(){
api.callHttpClient(something, something, something);
expect(callback.method).toHaveBeenCalledTimes(1);
});
});

How can I test that a function has not been called?

I'm testing router and have two functions, and I need to test if first function was called and second was not. There is method toHaveBeenCalled but there is no method to test if function was not called. How can I test that?
I have code like this:
var args, controller, router;
beforeEach(function() {
controller = {
foo: function(name, id) {
args = [].slice.call(arguments);
},
bar: function(name) {
}
};
spyOn(controller, "foo").and.callThrough();
spyOn(controller, "bar").and.callThrough();
router = new route();
router.match('/foo/bar/{{id}}--{{name}}', controller.foo);
router.match('/foo/baz/{{id}}--{{name}}', controller.bar);
router.exec('/foo/bar/10--hello');
});
it('foo route shuld be called', function() {
expect(controller.foo).toHaveBeenCalled();
});
it('bar route shoud not be called', function() {
// how to test if bar was not called?
});
Use the not operator:
expect(controller.bar).not.toHaveBeenCalled();

Jasmine does not reset spy after each test spec

I have the following spec.
describe("SN.ExitHistory", function() {
var exitHistory;
beforeEach(function() {
SN.Utils = jasmine.createSpy("utils").andCallFake(function() {
function readSNCookie(cookieName, key) {
return "google.com";
}
function isUndefinedOrNull(param) {
return (param == null) || (param === "null");
}
function createSNCookie(snCookieName, key, value, lifeTime) {
}
var me = {
readSNCookie : readSNCookie,
isUndefinedOrNull : isUndefinedOrNull,
createSNCookie : createSNCookie
};
return me;
})();
exitHistory = SN.ExitHistory();
});
it("return last exit link", function() {
expect(exitHistory.getLastExitLink()).toEqual("google.com");
});
});
exitHistory.getLastExitLink internally use SN.Utils.
After the test is done Jasmine does not remove the spy object utils. In next test suite also I can see the same utils present. Is there any way to reset the spy object after each test is done?
Instead of creating spy, if I create a new object for utils, behavior is same. Then what is the difference between a spy and actual object in this scenario.
Correct me if I am wrong.
I had the same problem some time ago and after days of struggling I found the solution. If you use the other way your spy will be reseted, so try with
spyOn(SN, 'Utils');
Spies are described here:
https://github.com/pivotal/jasmine/wiki/Spies
Use spyOn and declare your spies within a before block inside of a describe spec block and the spies will be cleaned up when each spec is torn down.
aSpec.js
describe('something', () => {
beforeAll(() => spyOn(someObject, 'someMethod').and.returnValue('foo'));
it('is spied on', () => {
expect(someObject.someMethod()).toEqual('foo');
});
});
anotherSpec.js
describe('something else', () => {
beforeAll(() => spyOn(someObject, 'someMethod').and.returnValue('bar'));
it('is spied on', () => {
expect(someObject.someMethod()).toEqual('bar');
});
});

Categories

Resources