dwyl / aws-sdk-mock

:rainbow: AWSomocks for Javascript/Node.js aws-sdk tested, documented & maintained. Contributions welcome!
Apache License 2.0
1.11k stars 110 forks source link

Restore function not working #148

Open cSchubes opened 6 years ago

cSchubes commented 6 years ago

Hi all,

I am attempting to mock an S3 getObject call, but I need it to be mocked differently in different tests. This problem is discussed in other issues and I have organized my tests in the way those issues recommend. Specifically, I:

  1. Set my SDK instance explicitly using setSDKInstance(AWS_SDK)
  2. Set the mock using AWS.mock at the beginning of each test.
  3. Create a new s3 instance after this mock is set.
  4. Call `AWS.restore('S3') after each test.

The restore call is where things are going wrong. I went and added some logging statements to index.js in the aws-sdk-mock package to see what was happening, and the function is definitely doing the right things - but for some reason the subsequent test will use the previous s3 mock. Example test suite is below. Any help is greatly appreciated!!

describe('successful-tests', () => {

  afterEach(async () => {
    await clearTable(UnprocessedImage)
    await clearTable(ProcessedImage)
    AWS.restore('S3')
  })

  test('clean-test', async () => {
    console.log('clean')
    expect.assertions(2)
    AWS.mock('S3', 'getObject', (params, callback) => {
      callback(null, {
        body: 'test 1',
      })
    })
    const s3 = new AWS_SDK.S3({ region: config.region });
    (axios as any).post.mockResolvedValue(DEEPGREEN_CLEAN_RESPONSE)
    await initializeTable(db, process.env.UNPROCESSED_IMAGE_TABLE_NAME)
    await loadSeed(UnprocessedImage, UNPROCESSED_SEED)
    // exectutes the given lambda locally using the provided event
    await new Promise(resolve =>
      lambdaLocal.execute({
        event: {},
        lambdaHandler: 'processUnprocessedImages',
        lambdaPath: path.join(__dirname, '../handler.ts'),
        region: 'us-west-2',
        verboseLevel: 3,
        callback: () => {
          resolve()
        },
      })
    )
    let remainingUnprocessed = 0
    for (let i = 0; i < 3; i++) {
      let entry = await getEntry(UnprocessedImage, i)
      if (entry.length !== 0) {
        remainingUnprocessed++
      }
    }
    expect(remainingUnprocessed).toBe(0)
    const processedEntries = await executeQuery(ProcessedImage.query(TESTING_CAMERA_ID))
    expect(processedEntries.length).toBe(3)
  })

  test('predictions-test', async () => {
    console.log('predict')
    expect.assertions(5)
    AWS.mock('S3', 'getObject', (params, callback) => {
      callback(null, {
        body: 'test 2',
      })
    })
    const s3 = new AWS_SDK.S3({ region: config.region });
    (axios as any).post.mockResolvedValue(DEEPGREEN_PREDICTIONS_RESPONSE)
    await initializeTable(db, process.env.UNPROCESSED_IMAGE_TABLE_NAME)
    await loadSeed(UnprocessedImage, UNPROCESSED_SEED)
    // exectutes the given lambda locally using the provided event
    await new Promise(resolve =>
      lambdaLocal.execute({
        event: {},
        lambdaHandler: 'processUnprocessedImages',
        lambdaPath: path.join(__dirname, '../handler.ts'),
        region: 'us-west-2',
        verboseLevel: 3,
        callback: () => {
          resolve()
        },
      })
    )
    let remainingUnprocessed = 0
    for (let i = 0; i < 3; i++) {
      let entry = await getEntry(UnprocessedImage, i)
      if (entry.length !== 0) {
        remainingUnprocessed++
      }
    }
    expect(remainingUnprocessed).toBe(0)
    const processedEntries = await executeQuery(ProcessedImage.query(TESTING_CAMERA_ID))
    expect(processedEntries.length).toBe(3)
    for (let entry of processedEntries) {
      expect(entry.attrs.predictions.length).toBe(2)
    }
  })
})
tylersmith34 commented 6 years ago

I'm having a similar problem with the EC2 service. I have tests using version 1.7.0 that works but the latest does not.

caal-15 commented 5 years ago

I'm having the same issue :(

punk-dev-robot commented 4 years ago

same here unfortunately

leeroyrose commented 4 years ago

Same here, are there any workarounds other than calling remock subsequent times?

leeroyrose commented 4 years ago

I noticed the issue went away when running tests serially.

fzaffarana commented 4 years ago

Hi!

I had the same issue with s3 + restore function, so this was my workaround:

const AWS = require('aws-sdk');

// Environment
const { AWS_REGION } = process.env;

AWS.config.update({ region: AWS_REGION });

const deleteModule = module => delete require.cache[require.resolve(module)];

const requireUncached = module => {
  deleteModule(module);
  return require(module);
};

describe('some tests', async () => {
  let AWSMock;

  beforeEach(async () => {
    AWSMock = requireUncached('aws-sdk-mock');
    AWSMock.setSDKInstance(AWS);
  });

  after(async () => {
    deleteModule('aws-sdk-mock');
  });

  afterEach(async () => {
    AWSMock.restore();
  });

  ...
jrtm885 commented 4 years ago

In my case I have been working with DynamoDB. To restore command works I have called this way: AWSMock.restore('DynamoDB.DocumentClient') instead of AWSMock.restore('DynamoDB');