Reputation: 2171
I want to mock a GCP bucket but Typescript is yelling because of typings.
Here's an extract of a Class I want to test:
private storage = new Storage({
projectId: 'PROJECT_NAME',
keyFilename: env.gcpKeyFilename,
});
get bucket() {
return this.storage.bucket('fundee-assets');
}
private async _downloadFromBucket(name) {
const file = this.bucket.file(`${name}`);
const destination = `${name}`.split('/').pop();
await file.download({ destination, validation: false });
return destination;
}
I wan't to mock a part of the GCP bucket in jest. So I tried:
jest.spyOn(service, 'bucket', 'get').mockImplementationOnce(
()=>{
return {
file(name){
return {
download(dest, validation){
return dest;
}
};
}
}
}
)
However typescript yells because it doesn't have all the prperties of a GCP Bucket typings:
Type '{ file(name: string): { download(dest: any, validation: any): any; }; }' is missing the following properties from type 'Bucket': name, storage, acl, iam, and 52 more.
Any idea on how to bypass this or I am doing the test completely wrong?
Upvotes: 1
Views: 2265
Reputation: 102277
Here is a solution based on:
"@google-cloud/storage": "^3.0.2",
"jest": "^23.6.0",
"ts-jest": "^23.10.4",
"typescript": "^3.0.3"
StorageService.ts
:
import { Storage } from '@google-cloud/storage';
class StorageService {
private storage = new Storage({
projectId: 'PROJECT_NAME',
keyFilename: ''
});
get bucket() {
return this.storage.bucket('fundee-assets');
}
private async _downloadFromBucket(name) {
const file = this.bucket.file(`${name}`);
const destination = `${name}`.split('/').pop();
await file.download({ destination, validation: false });
return destination;
}
}
export { StorageService };
Unit test:
import { StorageService } from './';
const mockedFile = {
download: jest.fn()
};
const mockedBucket = {
file: jest.fn(() => mockedFile)
};
const mockedStorage = {
bucket: jest.fn(() => mockedBucket)
};
const storageService = new StorageService();
jest.mock('@google-cloud/storage', () => {
return {
Storage: jest.fn(() => mockedStorage)
};
});
describe('StorageService', () => {
describe('#_downloadFromBucket', () => {
it('t1', async () => {
const name = 'jest/ts';
// tslint:disable-next-line: no-string-literal
const actualValue = await storageService['_downloadFromBucket'](name);
expect(mockedBucket.file).toBeCalledWith(name);
expect(mockedFile.download).toBeCalledWith({ destination: 'ts', validation: false });
expect(actualValue).toBe('ts');
});
});
});
Unit Test result:
PASS src/__tests__/cloud-storage/57724058/index.spec.ts
StorageService
#_downloadFromBucket
✓ t1 (9ms)
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 3.594s, estimated 4s
Upvotes: 4