Closed lebeier closed 4 years ago
Although it would be better to integrate support for getters into the library, it is possible to mock a getter whilst using jest-mock-extended
. Suppose you have an interface like this.
interface Strings {
readonly size: number;
item(index: number): string;
}
Just creating a mock for this interface using mock<Strings>
will allow you to mock the item
method. But since the type of size
is not a function, an expression like mockObject.size.mockReturnValue(3)
is a type error since you cannot call a method on an integer value.
However it is possible to define a property that uses a getter function directly on the implementation object that jest-mock-extended
uses to record the state for its mock object. We need to pass an empty object into the mock<>()
function so that we get a reference to this object. Consider the following code:
// Construct the mockers
const baseMock = {};
const mockStrings = mock<Strings>(baseMock);
const mockSizeGetter = jest.fn<number, []>();
Object.defineProperty(baseMock, 'size', { get: mockSizeGetter });
This code creates an object mockStrings
that mocks the Strings
interface. The jest mock function mockSizeGetter
is set to be the getter function for the size
property. You have to call defineProperty
on the baseMock
object after creating the mocker. Otherwise the mock<>()
function will attempt to alter it, which does not work since there is no setter function.
Now we can prepare the mockers to pretend to be a collection of three strings.
mockSizeGetter.mockReturnValue(3);
mockStrings.item
.mockReturnValueOnce('zero')
.mockReturnValueOnce('one')
.mockReturnValueOnce('two');
The following code demonstrates that the getter have been mocked.
const concatenate = (strings: Strings): string => {
let result = '';
for (let i = 0; i < strings.size; ++i) {
if (i > 0) {
result += ',';
}
result += strings.item(i);
}
return result;
}
expect(concatenate(mockStrings)).toEqual('zero,one,two');
Thanks for this example. While I am not working with any projects that are using jest framework at the moment, I will give it a try in the future. =)
Is it possible to mock getters? I always get the error
Cannot assign to 'xyz' because it is a read-only property