elasticsearch-js-mock icon indicating copy to clipboard operation
elasticsearch-js-mock copied to clipboard

How to create ResponseErrors in TypeScript

Open seantalbot-jisc opened this issue 4 years ago • 4 comments

Hi, thanks for this excellent library.

I'm trying to mock specific ResponseErrors in TypeScript but I'm getting stuck. The ResponseError constructor takes a huge amount of arguments that I'm unable to workaround without the compiler complaining or it not working.

This is as far as I've got:

import ClientMock from "@elastic/elasticsearch-mock";
import { Client, Connection } from "@elastic/elasticsearch";
import { ResponseError } from "@elastic/elasticsearch/lib/errors";

type RootCause = {
    type: string;
    reason: string;
};

export function addResponseError(
    clientMock: ClientMock,
    method: string,
    path: string,
    statusCode: number,
    rootCauses: RootCause[]
): void {
    const connection = clientMock.getConnection();
    clientMock.add(
        {
            method,
            path,
        },
        () => {
            return new ResponseError({
                body: {
                    errors: {
                        root_cause: rootCauses,
                    },
                    status: statusCode
                },
                statusCode,
                headers: {},
                meta: {
                    name: "foo",
                    context: {},
                    aborted: false,
                    attempts: 0,
                    request: {
                        id: 1,
                        options: {},
                        params: {
                            method,
                            path,
                        },
                    },
                    connection,
                },
                warnings: [],
            });
        }
    );
}

I had previously set connection to {} as Connection but I received no response in my test, so I thought I could use the one from ClientMock.getConnection() instead. However, I get an error:

Type 'typeof Connection' is missing the following properties from type 'Connection': url, ssl, id, headers, and 13 more.ts(2740) Transport.d.ts(63, 5): The expected type comes from property 'connection' which is declared here on type '{ context: Context; name: string | symbol; request: { params: TransportRequestParams; options: TransportRequestOptions; id: any; }; connection: Connection; attempts: number; aborted: boolean; sniff?: { ...; } | undefined; }'

Any suggestions?

seantalbot-jisc avatar Jul 06 '21 16:07 seantalbot-jisc

I'm using

"@elastic/elasticsearch-mock": "0.3.0",
"@elastic/elasticsearch": "7.9.1",

in case that helps.

seantalbot-jisc avatar Jul 06 '21 16:07 seantalbot-jisc

In case it's helpful to others, I worked around this by manually crafting one:

const err = Object.create(ResponseError.prototype);
Object.assign(err, {
    meta: {
        body: {
            status: 500,
            error: {
                type: "whatever",
            },
        },
        500,
        headers: {},
    },
});

This means the object returns true to instanceof ResponseError in my exception handler code and works for my use case.

seantalbot-jisc avatar Aug 10 '21 09:08 seantalbot-jisc

I'm getting stuck too. I'd like to use ResponseError to write tests for unexpected requests, but there is more code to generate ResponseError, in other words, the code for testing is getting mess. I'd like to know if there is a better way to mock ResponseError.

rokumura7 avatar Feb 15 '22 07:02 rokumura7

To me, this worked out:

      mock.add({ 
          method: 'POST', 
          path: `/my_index/_bulk`
      }, () => ( 
          new ResponseError({
              body: error,
              statusCode: 404,
              headers: {},
              meta: {} as any,
              warnings: [],
          })
      ));

Note: If you want to still return the "meta" prop, you can do the same strategy with the connection: connection: {} as any

Note2: "error" is a const defined earlier, with the desired content

nesjett avatar Mar 20 '22 15:03 nesjett