I'm working on testing an Apollo Server RESTDataSource
using Jest. My app is written in TypeScript. My class, CDCDataSource
extends the abstract class RESTDataSource which itself extends the abstract class DataSource
. RESTDataSource
has the method get
which allows you to pull data from an external REST data source. It is this method I wish to mock, since I wish to mock the external data source.
protected async get<TResult = any>(
path: string,
params?: URLSearchParamsInit,
init?: RequestInit,
): Promise<TResult> {
return this.fetch<TResult>(
Object.assign({ method: 'GET', path, params }, init),
);
}
However, when I try to mock this method using Jest's spyOn
-- following the second answer here: Jest: How to mock one specific method of a class --
import CDCDataSource from '../CDCDataSource';
test('Test', () => {
let dataSource = new CDCDataSource();
let spy = jest.spyOn(dataSource, 'get').mockImplementation(() => 'Hello');
expect(dataSource.get()).toBe('Hello');
However, I get the TypeScript error
TS2768: No overload matches this call
over the get
in jest.spyOn(dataSource,'get')
and I get
over the get
in
expect(dataSource.get()).toBe('Hello');
So it would seem that part of the issue is that this is a protect method -- I'm unclear how to test this method so as to be able to mock the API.
My tsconfig.json
is
{
"compilerOptions": {
"target": "ES6",
"lib": [
"esnext",
"dom"
],
"skipLibCheck": true,
"outDir": "dist",
"strict": false,
"forceConsistentCasingInFileNames": true,
"esModuleInterop": true,
"module": "commonjs",
"moduleResolution": "node",
"resolveJsonModule": true,
"isolatedModules": true,
"sourceMap": true,
"alwaysStrict": true,
},
"exclude": [
"node_modules"
]
}
This is a Node Apollo Server project (using Node 12.14.0 and TypeScript 3.8.3)
Thanks for any clues!
You are trying to access a protected
method.
If you don't want to or can't rearchitect your class, you can use ts-ignore
to suppress the error.
// @ts-ignore`
let spy = jest.spyOn(dataSource, 'get').mockImplementation(() => 'Hello');
Or you can extend the original class, with a class made only for testing, that will have a public method that will just proxy to the protected method.
test('Protected method',()=>{
class Test extends OriginalClass {
testProtected(){
super.protectedMethod()
}
}
let dataSource = new Test();
let spy = jest.spyOn(dataSource, 'testProtected').mockImplementation(() => 'Hello');
})