[Bugfix] (SOLVED) Error jest toHaveBeenCalledWith() with Array parameter

[Bugfix] (SOLVED) Error jest toHaveBeenCalledWith() with Array parameter

Problem description:

Context:

AWS typescript project that combines cloudformation, SAM and swagger for the API definitions:

  • aws-sdk: 2.742.0
  • jest: 26.4.2

After several change sin the code, the unit tests were adapted in order to satisfy the new requirements. Unexpectedly the calls performed to the jest method toHaveBeenCalledWith() to validate if the mocked method is correctly been called started to fail with that output:

image.png

That's the code of the unit test with the corresponding call:

      test('Dummy test', async () => {
        getSubscription.mockResolvedValue(subscriptionResponse);
        getProduct.mockResolvedValue(productResponse);
        getAsset.mockResolvedValue(assetDbItem);
        getEntity.mockResolvedValue(entity);

        await target.addInternalSubscription(CallbackPayload);

        expect(updateSubscriptions).toHaveBeenCalledWith('accountId', 'assetId', [{
          id: 'subscription_id',
          subscriptionNumber: subscriptionNumber,
          type: 'A',
          expiration: '2021-12-12',
          startDate: '2020-12-12',
          term: 12,
          status: 'ACTIVE',
          productType: 'CUSTOMER',
          autoRenew: false,
          category: 'CATEGORY1',
          channel: 'CHANNEL1',
          package: 'MAIN',
        }], LAST_UPDATED_DATE_TIME);

Solution:

As initially the parameter that was evaluated doesn't was an object, the strict evaluation of toHaveBeenCalledWith() provoked to fail. A simple and efficient way to solve this kind of issue is to use Jest partial matching.

What is Jest Partial Matching? When it's only needed to test part of an object, or a subset of an array, you can use partial matchers to avoid the full correspondence between the expected and received element to be tested.

In our example we have used objectContaining in order to only match on certain key/value pairs in the object param, What at the end, is the most important validation for our scenario.

Unit test fixed:

expect(updateSubscriptions).toHaveBeenCalledWith('accountId', 'assetId', 

expect.objectContaining([{
          id: 'subscription_id',
          subscriptionNumber: subscriptionNumber,
          type: 'A',
          expiration: '2021-12-12',
          startDate: '2020-12-12',
          term: 12,
          status: 'ACTIVE',
          productType: 'CUSTOMER',
          autoRenew: false,
          category: 'CATEGORY1',
          channel: 'CHANNEL1',
          package: 'MAIN',
        }]), LAST_UPDATED_DATE_TIME);