How to mock/replace getter function of object with Jest?
60,385
Solution 1
You could use Object.defineProperty
Object.defineProperty(myObj, 'prop', {
get: jest.fn(() => 'bar'),
set: jest.fn()
});
Solution 2
For anyone else stumbling across this answer, Jest 22.1.0 introduced the ability to spy on getter and setter methods.
Edit: like in scieslak's answer below, because you can spy on getter and setter methods, you can use Jest mocks with them, just like with any other function:
class MyClass {
get something() {
return 'foo'
}
}
jest.spyOn(MyClass, 'something', 'get').mockReturnValue('bar')
const something = new MyClass().something
expect(something).toEqual('bar')
Solution 3
If you care about spying only, go for @Franey 's answer. However if you actually need to stub a value for the getter, this is how you can do it:
class Awesomeness {
get isAwesome() {
return true
}
}
describe('Awesomeness', () => {
it('is not always awesome', () => {
const awesomeness = new Awesomeness
jest.spyOn(awesomeness, 'isAwesome', 'get').mockReturnValue(false)
expect(awesomeness.isAwesome).toEqual(false)
})
})
Author by
I_like_foxes
Student... Being curious and learning, learning, learning...
Updated on July 05, 2022Comments
-
I_like_foxes almost 2 years
In Sinon I can do the following:
var myObj = { prop: 'foo' }; sinon.stub(myObj, 'prop').get(function getterFn() { return 'bar'; }); myObj.prop; // 'bar'
But how can I do the same with Jest? I can't just overwrite the function with something like
jest.fn()
, because it won't replace the getter"can't set the value of get"
-
I_like_foxes about 7 yearsThank you a lot, that works. Sometimes I notice I don't need more knowledge about some library/framework but the fundamental workings of JavaScript. May I ask one follow up question: How would I mock this function if I wanted my mock to replace the original function just one time but the next call should handled by the original function again?
-
shoke over 6 yearsThis works, but when I try to do it in my beforeEach() call it fails with
Cannot redefine property
. Why is this? -
cgat over 6 years@clu add
configurable: true
to your thedefineProperty
function. That should do the trick -
Misu almost 6 yearsNotice that - in contrast with mocks - it won't "unmock" your getter at the end of each test case, so - if other tests rely on the original return value of the getter - you may get different results running one test and the whole suite.
-
Sandeep vashisth over 5 yearsgetting cannot redefine property.
-
Franey about 5 years@taystack Being able to spy on the getters/setters was a necessary step toward being able to mock them like a regular function. I updated my answer to be more explicit about that and added a mock to the example code.
-
Tomasz Kula almost 5 yearsScroll down to Franey answer. It is more recent.
-
Fabrizio Bertoglio over 4 years
something property does not exist
with[email protected]
with["module:metro-react-native-babel-preset"
, while it works fine with scieslak solution which sets the spy exactly on theawesomeness
instance. Inrspec
I would use a method calledany_instance
and I would mock/stubany_instance
of that class. There is a clear difference in syntax between the jest officialspyOn
documentation and your example. In that example jest spys on an object literal -
Fabrizio Bertoglio over 4 years
const video = { get play() { return true; },};
-
Ran Lottem about 4 yearsI got an error that the property does not exist. It also looks like the other answer calls
spyOn
on the class whereas you call it on an instance. -
Mike P. about 4 years@fabrizo jest.spyOn(MyClass, 'something', 'get').mockReturnValue('bar') should be jest.spyOn(MyClass.prototype, 'something', 'get').mockReturnValue('bar')
-
mdhvn almost 4 yearsI'm seeing the same thing - 'property does not exist' - when calling on an instance.
-
Valentine Shi over 2 yearsThis is really good as this allows working with the complex object's fixture - its POJO representation. This especially useful when you have to supply that object as dependency and would not like to bother creating the actual object - actually keeping yourself away from integration tesing when it is not yet desirable.