Reputation: 13206
I'm testing the following method:
startScriptLoad(): void {
const documentDefaultView = this.getDocumentDefaultView();
if (documentDefaultView) {
const twitterData: ICourseContentElementEmbedTweetWidgetData = this.getTwitterWidgetData() ?? {
// eslint-disable-next-line @typescript-eslint/no-empty-function
ready: () => {},
_e: [],
};
if (this.scriptExists()) {
((this.document.defaultView as unknown) as ICourseContentElementEmbedTweetDocument)[
this.TWITTER_OBJECT
] = twitterData;
return;
}
this.appendScriptToDOM();
twitterData._e = [];
twitterData.ready = (callback: () => void) => {
twitterData._e.push(callback);
};
((this.document.defaultView as unknown) as ICourseContentElementEmbedTweetDocument)[
this.TWITTER_OBJECT
] = twitterData;
}
}
with the following test:
describe('startScriptLoad()', () => {
it('should load script', () => {
jest.spyOn(service, 'getDocumentDefaultView');
jest.spyOn(service, 'appendScriptToDOM');
service.startScriptLoad();
expect(service.getDocumentDefaultView).toHaveBeenCalled();
expect(service.appendScriptToDOM).toHaveBeenCalled();
});
});
For some reason, I can't get coverage for the following lines of code in startScriptLoad():
twitterData.ready = (callback: () => void) => {
twitterData._e.push(callback);
};
Is there a way that I can mock the call to the callback method somehow?
Upvotes: 0
Views: 889
Reputation: 102207
Use Proxy to create a proxy for the mocked object, which can intercept and redefine fundamental operations for that object. Which means we can use handler.set() set up a trap for setting the ready
private method on mTwitterData
object.
The trap is: assign the ready
anonymous method to a variable like _ready
. After getting it, call it manually for testing later.
service.ts
:
export class SomeService {
getTwitterWidgetData() {
return {} as any;
}
startScriptLoad(): void {
const twitterData = this.getTwitterWidgetData();
twitterData._e = [];
twitterData.ready = (callback: () => void) => {
twitterData._e.push(callback);
};
}
}
service.test.ts
:
import { SomeService } from './service';
describe('69041800', () => {
test('should pass', () => {
const service = new SomeService();
let _ready;
const mTwitterData = new Proxy({} as any, {
set: (obj, prop, value) => {
if (prop === 'ready') {
_ready = value;
}
obj[prop] = value;
return true;
},
});
const getTwitterWidgetDataSpy = jest.spyOn(service, 'getTwitterWidgetData').mockReturnValue(mTwitterData);
service.startScriptLoad();
expect(getTwitterWidgetDataSpy).toBeCalledTimes(1);
// test ready private method
const mCallback = jest.fn();
_ready(mCallback);
expect(mTwitterData._e).toEqual([mCallback]);
getTwitterWidgetDataSpy.mockRestore();
});
});
test result:
PASS examples/69041800/service.test.ts (9.519 s)
69041800
✓ should pass (4 ms)
------------|---------|----------|---------|---------|-------------------
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s
------------|---------|----------|---------|---------|-------------------
All files | 83.33 | 100 | 66.67 | 83.33 |
service.ts | 83.33 | 100 | 66.67 | 83.33 | 3
------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 10.148 s
Upvotes: 1