title: Jest mocking google-cloud/storage typescript
body: <p>I have been trying to mock the @google-cloud/storage for my implementation so that I could test it without having to hit the cloud-storge in gcp and so far it has all been in vain
  I have tried to mock the node_module scope folder using the jest doc and that didnt work out
  Hence I tried using below</p>
  
  <p>This is my implementation class</p>
  
  <pre><code>import { GcloudAuthenticationInstance } from '../common/services/gcloud.authentication';
  import * as fs from 'fs';
  import pump from 'pump';
  import pino from 'pino';
  import * as _ from 'lodash';
  
  import {
      ENV_NAME_DEV,
      GCLOUD_DATABASE_BUCKET_DEV,
      GCLOUD_DATABASE_BUCKET_PROD,
      GCLOUD_ENV_STR_BUCKET_NAME,
      GCLOUD_STORED_FILE_NAME_DEV,
      GCLOUD_STORED_FILE_NAME_PROD,
      GCLOUD_UPLOAD_FILE_DEV_LOCAL_PATH,
      GCLOUD_UPLOAD_FILE_PROD_LOCAL_PATH,
  } from '../common/util/app.constants';
  import { PinoLoggerServiceInstance } from '../common/services/pino.logger.service';
  import { AppUtilServiceInstance } from '../common/services/app.util.service';
  export const uploadEnvFiles = async (env_name: string) =&gt; {
      const LOGGER: pino.Logger = PinoLoggerServiceInstance.getLogger(__filename);
  
      return new Promise(async (res, rej) =&gt; {
         // This just returns the Storage() instance with keyFileName and projectID
          //of google cloud console being set so authentication takes place
          const str = GcloudAuthenticationInstance.createGcloudAuthenticationBucket();
  
          const bucketToUpload = GCLOUD_ENV_STR_BUCKET_NAME;
          let uploadLocalFilePath;
          let destinationBucketPath;
          if (!AppUtilServiceInstance.isNullOrUndefined(env_name)) {
              uploadLocalFilePath = ENV_NAME_DEV === env_name ? GCLOUD_UPLOAD_FILE_DEV_LOCAL_PATH : GCLOUD_UPLOAD_FILE_PROD_LOCAL_PATH;
              destinationBucketPath = ENV_NAME_DEV === env_name ? GCLOUD_DATABASE_BUCKET_DEV : GCLOUD_DATABASE_BUCKET_PROD;
          }
          LOGGER.info('after authentication');
          pump(
              fs.createReadStream(uploadLocalFilePath),
              str
                  .bucket(bucketToUpload)
                  .file(destinationBucketPath)
                  .createWriteStream({
                      gzip: true,
                      public: true,
                      resumable: true,
                  })
          )
              .on('error', (err) =&gt; {
                  LOGGER.error('Error occured in uploading:', err);
                  rej({ status: 'Error', error: err, code: 500 });
              })
              .on('finish', () =&gt; {
                  LOGGER.info('Successfully uploaded the file');
                  res({ status: 'Success', code: 201, error: null });
              });
      });
  };
  
  export const downloadEnvFiles = async (env_name): Promise&lt;any&gt; =&gt; {
      const LOGGER: pino.Logger = PinoLoggerServiceInstance.getLogger(__filename);
  
      return new Promise(async (res, rej) =&gt; {
          const str = GcloudAuthenticationInstance.createGcloudAuthenticationBucket();
          try {
              const [files] = await str.bucket(GCLOUD_ENV_STR_BUCKET_NAME).getFiles();
  
              const filteredFile =
                  ENV_NAME_DEV === env_name
                      ? _.find(files, (file) =&gt; {
                          c
                              return file.name.includes(GCLOUD_STORED_FILE_NAME_DEV);
                        })
                      : _.find(files, (file) =&gt; {
  
                              return file.name.includes(GCLOUD_STORED_FILE_NAME_PROD);
                        });
              res({
                  status: 'Success',
                  code: 200,
          error: null,
                  stream: str
                      .bucket(GCLOUD_ENV_STR_BUCKET_NAME)
                      .file(filteredFile.name)
                      .createReadStream()
              });
          } catch (err) {
              LOGGER.error('Error in retrieving files from gcloud:'+err);
              rej({ status: 'Error', error: err, code: 500 });
          }
      });
  };
  </code></pre>
  
  <p>This is my jest ts</p>
  
  <pre><code>bucket.operations.int.spec.ts
  </code></pre>
  
  <p>I've tried to include the mock inline</p>
  
  <pre><code> import { GcloudAuthenticationInstance } from '../common/services/gcloud.authentication';
  const { Storage } = require('@google-cloud/storage');
  const { Bucket } = require('@google-cloud/storage');
  import { File } from '@google-cloud/storage';
  import { mocked } from 'ts-jest/utils'
  const fs = require('fs');
  import * as path from 'path';
  import pump from 'pump';
  import * as BucketOperations from './bucket.operations';
  import { GCLOUD_ENV_STR_BUCKET_NAME } from '../common/util/app.constants';
  const { PassThrough } = require('stream');
  const fsMock = jest.mock('fs');
  
  // Here we are trying to mock pump with a function returned
  // since pump () is the actual fucntion, we are mocking the function to return a value
  // which is just a value of "on" eventlistener.. so we indicate that this will be substituted
  // with another mocked function
  jest.genMockFromModule('@google-cloud/storage');
  jest.mock('@google-cloud/storage', () =&gt; {
  
    const mockedFile = jest.fn().mockImplementation(() =&gt; {
      return {
        File: jest.fn().mockImplementation(() =&gt; {
          return {
            name: 'dev.txt',
            createReadStream: jest
              .fn()
              .mockReturnValue(
                fs.createReadStream(
                  path.resolve(process.cwd(), './tests/cloud-storage/sample-read.txt')
                )
              ),
            createWriteStream: jest
              .fn()
              .mockReturnValue(
                fs.createWriteStream(
                  path.resolve(process.cwd(), './tests/cloud-storage/sample-write.txt')
                )
              )
          };
        })
      };
    });
  
    const mockedBUcket = jest.fn().mockImplementation(() =&gt; {
      return {
        Bucket: jest.fn().mockImplementation(() =&gt; {
          return {
            constructor: jest.fn().mockReturnValue('test-bucket'),
            getFiles: jest.fn().mockReturnValue([mockedFile])
          }
        })
      }
    });
  
  
    return {
      Storage: jest.fn().mockImplementation(() =&gt; {
        return {
          constructor: jest.fn().mockReturnValue('test-storage'),
          bucket: mockedBUcket,
          file: mockedFile,
          createWriteStream: jest.fn().mockImplementation(() =&gt;
            fs.createWriteStream(path.resolve(process.cwd(), './tests/cloud-storage/sample-write.txt')))
        };
      })
    };
  });
  
  jest.mock('pump', () =&gt; {
    const mPump = { on: jest.fn() };
    return jest.fn(() =&gt; mPump);
  });
  
  describe('Test suite for testing bucket operations', () =&gt; {
    const mockedStorage = mocked(Storage, true);
    const mockeddFile = mocked(File, true);
    const mockeddBucket = mocked(Bucket, true);
    function cancelCloudStorageMock() {
      //mockCloudStorage.unmock('@google-cloud/storage');
      mockedStorage.mockClear();
      mockeddBucket.mockClear();
      mockeddFile.mockClear();
      jest.unmock('@google-cloud/storage');
      jest.requireActual('@google-cloud/storage');
    }
  
    function cancelFsMock() {
      jest.unmock('fs');
      jest.requireActual('fs');
    }
  
    afterEach(() =&gt; {
      jest.clearAllMocks();
      //jest.restoreAllMocks();
    });
    test('test for uploadfiles - success', async (done) =&gt; {
      cancelFsMock();
      pump().on = jest.fn(function(this: any, event, callback) {
        if (event === 'finish') {
          callback();
        }
        return this;
      });
      const actual = await BucketOperations.uploadEnvFiles('dev');
  
      expect(actual).toEqual(
        expect.objectContaining({
          status: 'Success',
          code: 201,
        })
      );
      done();
    });
  
  
    test('test downloadEnvFiles  - success', async (done) =&gt; {
      jest.unmock('fs');
  
      const fMock = (File.prototype.constructor = jest.fn().mockImplementation(() =&gt; {
        return {
          storage: new Storage(),
          bucket: 'testBucket',
          acl: 'test-acl',
          name: 'dev.txt',
          parent: 'parent bucket',
        };
      }));
  
      const bucketGetFilMock = (Bucket.prototype.getFiles = jest.fn().mockImplementation(() =&gt; {
        return [fMock];
      }));
  
      // Get files should be an array of File from google-cloud-storage
      //Bucket.prototype.getFiles = jest.fn().mockReturnValue([mockedFsConstructor]);
  
      //Storage.prototype.bucket = jest.fn().mockReturnValue(new Storage());
  
      const mockReadable = new PassThrough();
      const mockWritable = new PassThrough();
  
      jest.spyOn(fs, 'createReadStream').mockReturnValue(
        fs.createWriteStream(path.resolve(process.cwd(), './tests/cloud-storage/sample-read.txt'))
      );
      await BucketOperations.downloadEnvFiles('dev');
  
      done();
    });
  });
  </code></pre>
  
  <p>This is the exception I end up with. Upon debugging I see that the mocked instances are trying to execute, but it doesn't execute the file method in Storage mock. This is not available in @google-cloud/storage but I did try to mock it. Is there a way to mock just the usage of google-cloud/storage using jest?</p>
  
  <p>EDIT:
   Here is the exception:</p>
  
  <pre><code>TypeError: str.bucket(...).file is not a function
  
      at /home/vijaykumar/Documents/Code/Nestjs/cloud-storage-app/src/gcloud/bucket.operations.ts:37:6
      at Generator.next (&lt;anonymous&gt;)
      at /home/vijaykumar/Documents/Code/Nestjs/cloud-storage-app/src/gcloud/bucket.operations.ts:8:71
      at new Promise (&lt;anonymous&gt;)
      at Object.&lt;anonymous&gt;.__awaiter (/home/vijaykumar/Documents/Code/Nestjs/cloud-storage-app/src/gcloud/bucket.operations.ts:4:12)
      at /home/vijaykumar/Documents/Code/Nestjs/cloud-storage-app/src/gcloud/bucket.operations.ts:22:40
      at new Promise (&lt;anonymous&gt;)
      at /home/vijaykumar/Documents/Code/Nestjs/cloud-storage-app/src/gcloud/bucket.operations.ts:22:9
  </code></pre>