'Mock OpenSearch Client in jest unit test

I'm trying to mock out the opensearch client for testing purposes and am running into an error. My app is using OpenSearch (@opensearch-project/opensearch) and now I'm looking for a good mock or an example of how to mock the client in a way that I can load mock data into an opensearch instance to be queried against in tests.

I'm trying to use @elastic/elasticsearch-mock since they are the same thing under the hood, elastic and opennsearch. Using mock.add() does not seem to help anything in the code snippet below, I still get the same error.

Any ideas on the issues I'm facing below would be so appreciated, thank you all!

Here is an example of how I'm trying to use it now (that won't work):

// test file

import MockElasticSearch from '@elastic/elasticsearch-mock';
import { Client as MockClient } from '@opensearch-project/opensearch';
import { mocked } from 'ts-jest/utils';

// Mock above tests that does not work
jest.mock('../elasticsearchConnection', () => {
  const esMock = new MockElasticSearch();
  const elasticsearchClient = new MockClient({
    node: 'http://localhost:9200',
    Connection: esMock.getConnection() as any,
  });
  return { elasticsearchClient };
});

it.only('should call myQuery with the correct query', async () => {
      const mockId = '5555';
      const mockItem = createMockItem();
      const mockedResults = [
        {
          id: '2222',
          name: 'TESTER NAME',
        },
        {
          id: '3333',
          name: 'TEST NAME',
        },
      ];

      const mockedResponse = {
        body: {
          hits: {
            hits: [
              {
                _index: 'items',
                _source: {
                  ...mockItem,
                  details: {
                    ...mockItem.details,
                    id: mockId,
                  },
                },
              },
            ],
          },
        },
      };

      await myQuery(mockId);

      expect(elasticsearchClient.search).toHaveBeenCalledWith(
{
        index: 'myIndex',
        size: 10000,
        from: 0,
        body: {
          query: {
            bool: {
              must: [
                {
                  match: {
                    'details.id': mockId,
                  },
                },
              ],
            },
          },
          sort: [{ 'name.keyword': { order: 'asc' } }],
        },
      });
    });
  });

The error I receive is TypeError: Cannot read property 'body' of undefined and it is pointing to return response.body.hits.hits.map((hit) => ... in my local opensearch query file inside of myQuery() which I'm positive is already working perfectly.

// query file

export const myQuery = async (
  id: string
): Promise<(Item | null)[]> => {
  const response = await elasticsearchClient.search<
    SearchResponse<ItemSchemaType>
  >({
    index: 'myIndex,
    size: 10000, // This is set arbitrarily high to get all values
    from: 0,
    body: {
      query: {
        bool: {
          must: [
            {
              match: {
                'details.id': id,
              },
            },
          ],
        },
      },
      sort: [{ 'name.keyword': { order: 'asc' } }],
    },
  });
  return response.body.hits.hits.map((hit) =>
    hit._source ? hit._source : null
  );
};

My understanding is that elasticsearch-js-mock is only compatible with elastic/elasticsearch version <= 7 and I'm trying to mock out the Client from opensearch version 1.0.0. The elastic version I see that we're using is 7.13.0. Does any of this have anything to do with the error?



Solution 1:[1]

This worked for me

import { Client } from '@opensearch-project/opensearch'
import Mock from '@elastic/elasticsearch-mock'

const mock = new Mock()
const mockClient = new Client({
  node: 'http://localhost:9200',
  Connection: mock.getConnection()
})

mock.add({
  method: ['GET', 'POST'],
  path: ['/_search', '/:index/_search']
}, () => {
  return {
    hits: {
      total: { value: 1, relation: 'eq' },
      hits: [
        { 
          _source: {
            baz: 'faz' 
          }
        }
      ]
    }
  }
})

My modules

$ npm ls @opensearch-project/opensearch
??? @opensearch-project/[email protected] 

$ npm ls @elastic/elasticsearch-mock
??? @elastic/[email protected] 

$ npm ls @elastic/elasticsearch
??? @elastic/[email protected] 

Make sure you mock the correct endpoints

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Murty