Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Making assertions about how the mock was used #9

Open
plumdog opened this issue May 7, 2020 · 2 comments
Open

Making assertions about how the mock was used #9

plumdog opened this issue May 7, 2020 · 2 comments
Labels

Comments

@plumdog
Copy link

plumdog commented May 7, 2020

Particularly when using wildcards, I might want to make assertions about how the client was used.

Sample (with workaround to show want I want to do - should run with npx ts-node if the client and the mock are installed):

import { Client } from '@elastic/elasticsearch';
import Mock, { MockPattern } from '@elastic/elasticsearch-mock';

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

// Prepare the mock for my "test"
// Use this to track calls (could use something more sophisticated like jest.fn)
const esIndexMockCalls: Array<MockPattern> = [];
mock.add({
    method: ['POST', 'PUT'],
    path: '/:index/_doc/:id',
}, (params: MockPattern) => {
    // Record the call
    esIndexMockCalls.push(params);
    return { status: 'ok' };
});

// Run the "test"
client.index({
    index: 'myindex',
    id: 'mydocument',
    body: {
        foo: 'bar',
    },
}).then(() => {
    // Make "assertions"
    // Check that only one call was made
    if (esIndexMockCalls.length !== 1) {
        throw new Error('Expected one call');
    }
    // Check that we indexed the right thing in the right place
    if (esIndexMockCalls[0].path !== '/myindex/_doc/mydocument') {
        throw new Error('Expected index of mydocument in myindex');
    }
    console.log('Indexed mydocument in myindex as expected');
});

The alternative is to put these assertions in the callback, eg:

mock.add({
    method: ['POST', 'PUT'],
    path: '/:index/_doc/:id',
}, (params: MockPattern) => {
    if (params.path !== 'myindex/_doc/mydocument' {
        throw new Error('Unexpected index path');
    }
    return { status: 'ok' };
});

but this doesn't allow for things like checking how many calls were made. Eg if I have code where I index multiple documents in parallel, I want to be able to check that each one got indexed exactly once.

Is something like this handled by the mock client? Or is using something like jest.fn to track the calls from within the callback the best way of going about this?

@delvedor
Copy link
Member

Hello! Currently, it's not possible, but it would be a nice feature!
It should be opt-in in my opinion, so if a user want to use a different mock method (jest.fn for example), they can do it.
Would you like to work on it? :)

@iamEAP
Copy link

iamEAP commented Oct 9, 2021

For future wanderers who find themselves here: a trick I used to get this functionality is as follows:

const deleteSpy = jest.fn().mockReturnValue({});
mock.add({
  method: 'DELETE',
  path: '/some-specific-index-name',
}, deleteSpy);

await client.indices.delete({
  index: 'some-specific-index-name',
});

expect(deleteSpy).toHaveBeenCalled();

It's not great, because a failure doesn't make a distinction between "wasn't actually called at all" and "was called with the wrong index name." You could work around this by matching any index and asserting the shape of the call to the deleteSpy, but it's quite verbose.

Naturally, the same approach (of passing a spy with mock implementation as the response body getter) will work on any method/path.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants