The “cannot spy on a primitive value; undefined given” error occurs when you try to spy on or create a spy for a primitive value (such as a string, number, boolean, etc.), but the value passed to the spy function is undefined.
In JavaScript, primitive values are not objects and do not have any methods or properties. Therefore, spies created by testing frameworks (such as Jasmine, Jest, etc.) cannot be attached to them.
To understand this better, let’s consider an example using Jasmine:
// Code under test
const myFunction = (text) => {
if (typeof text !== 'string') {
throw new Error('Value must be a string');
}
console.log(text);
};
// Test case
describe('myFunction', () => {
it('should log the provided text', () => {
const spy = spyOn(console, 'log');
myFunction(undefined);
expect(spy).toHaveBeenCalled();
});
});
In the above example, we are trying to spy on the “console.log” function to ensure that it is called by “myFunction”. However, when we call “myFunction(undefined)”, it throws the error “cannot spy on a primitive value; undefined given”.
This error occurs because “undefined” is a primitive value, and spies cannot be attached to it. To resolve this issue, we need to pass a valid string value instead of undefined when calling “myFunction”.
Here’s the corrected test case:
// Test case (corrected)
describe('myFunction', () => {
it('should log the provided text', () => {
const spy = spyOn(console, 'log');
myFunction('Hello');
expect(spy).toHaveBeenCalled();
});
});
In the corrected test case, we pass the string value “Hello” instead of undefined when calling “myFunction”. Now the spy will be attached to the console.log function correctly, and the test will pass without any errors.