简体   繁体   中英

Jest mock unnable to pick up error throw?

I have some code that calls an api. I am testing the functionality that is nested in try catches, and checking the correct behaviour happens when I throw an error with certain values.

async function createDeployment(namespace, config, name) {
  try {
    await k8sDeploymentApi.createNamespacedDeployment(namespace, config, true);
    console.log('Successful deployment');
    return Promise.resolve(true);
  } catch (e) {
    console.log(JSON.stringify(e));
    if (e.response.statusCode === HTTP_CONFLICT) {
      try {
        await k8sDeploymentApi.replaceNamespacedDeployment(name, namespace, config, true);
        console.log('Successfully replaced deployment');
        return Promise.resolve(true);
      } catch (error) {
        return Promise.reject(error);
      }
    }
    return Promise.reject(e);
  }
}

I am mocking out the api calls node module here

var mockListNamespacedIngress;
var mockCreateNamespacedDeployment;
var mockReplaceNamespacedDeployment;
jest.mock('@kubernetes/client-node', () => {
  mockListNamespacedIngress = jest.fn();
  mockCreateNamespacedDeployment = jest.fn();
  mockReplaceNamespacedDeployment = jest.fn();
  return {
    KubeConfig: jest.fn().mockImplementation(() => ({
      loadFromCluster: jest.fn(),
      loadFromDefault: jest.fn(),
      makeApiClient: () => ({
        listNamespacedIngress: mockListNamespacedIngress,
        createNamespacedDeployment: mockCreateNamespacedDeployment,
        replaceNamespacedDeployment: mockReplaceNamespacedDeployment,
      }),
    })),
  };
});

And running the test here

    it.only('Should return a log of success if replaced deployment resolves', async () => {
      mockCreateNamespacedDeployment.mockRejectedValueOnce(() =>
        Promise.reject(new Error({ response: { statusCode: 409 } })),
      );

      mockReplaceNamespacedDeployment.mockResolvedValueOnce(true);

      // When
      await expect(createDeployment()).resolves.toEqual(true);
    });

However on the console.log(JSON.stringify(e)), I am only ever getting undefined coming back. So it does seem to throw the error, but gives no error object from the catch. Here is my full stacktrace

 ● Kubernetes deployment script tests › Kubernetes Calls › Should return a log of success if replaced deployment resolves

    expect(received).resolves.toEqual()

    Received promise rejected instead of resolved
    Rejected to value: [TypeError: Cannot read property 'statusCode' of undefined]

      143 |
      144 |       // When
    > 145 |       await expect(createDeployment()).resolves.toEqual(true);
          |             ^
      146 |     });
      147 |   });
      148 |

      at expect (node_modules/expect/build/index.js:134:15)
      at Object.it.only (src/__tests__/index.test.js:145:13)

  console.log
    Successful deployment

      at createDeployment (src/index.js:73:13)

  console.log
    undefined

      at createDeployment (src/index.js:76:13)

You can mock an async function throwing an Error like this

mockCreateNamespacedDeployment.mockRejectedValueOnce(new Error({ response: { statusCode: 409 } });

and then you can expect

await expect(createDeployment()).rejects.toThrow();

Btw in your async function you can replace all of the

- Promise.resolve(xxx)
+ return xxx

// and
- Promise.reject(xxx)
+ throw xxx

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM