Reputation: 1773
Here is the test code
var list = new List([1, 2, 3, 4]);
var list2 = new List([5, 1]);
beforeAll(function () {
spyOn(list.values, 'map').and.callThrough();
list.map(plusOne);
});
it('Array.prototype.map()', function () {
expect(list.values.map).not.toHaveBeenCalled();
});
This results in the following error 1) List must not call native Array function Array.prototype.map() Message:
Error: <toHaveBeenCalled> : Expected a spy, but got Function.
Usage: expect(<spyObj>).toHaveBeenCalled()
class List {
constructor(clist = []) {
this.values = clist;
}
map(f) {
var temp = [];
this.values.forEach((item, index) => {
temp.push(f(item));
});
this.values = temp;
return this;
}
}
module.exports = { List };
I do not think this is a unit test fail as such because I get the same message whether I call not.tohaveBeenCalled() or toHaveBeenCalled().
I am using node 8.9.4 and jasmine 2.8.0.
I believe the syntax is correct because when I run others code against these tests they pass. But my code causes this error.
My question is what does the above error mean? Regards,
Upvotes: 5
Views: 15163
Reputation: 4495
I just run the following test and it works on [email protected]
fit('Spy on map works', () => {
let someArray = [1, 3, 5];
spyOn(someArray, 'map').and.callThrough();
someArray.map(function(r){ console.log(r); });
expect(someArray.map).toHaveBeenCalled();
});
You might want to run this example to know if it works in your tests.
As I said in the comment your list map method overrides the list.values with a new array. Hence, the spy is not there anymore. try something like:
someArray.forEach((item, index) => {
someArray[index] = f(item);
});
To explain what is happening:
//WORKS
fit('Spy on map works', () => {
let someArray = [1, 3, 5];
spyOn(someArray, 'map').and.callThrough();
someArray.forEach((item, index) => {
someArray[index] = (item + '_t');
});
someArray.map(function(r){ console.log(r); });
expect(someArray.map).toHaveBeenCalled();
});
//FAILS because array is another object.
fit('Spy on map fails', () => {
let someArray = [1, 3, 5];
spyOn(someArray, 'map').and.callThrough();
let tempArray = [];
someArray.forEach((item, index) => {
tempArray.push(item + '_t');
});
someArray = tempArray;
someArray.map(function(r){ console.log(r); });
expect(someArray.map).toHaveBeenCalled();
});
However, you could just spy on prototype. Something like that:
spyOn(Array.prototype, 'map').and.callThrough();
And then, your test should work.
Upvotes: 4