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

New matcher: .toHaveBeenCalledBefore(mock) #98

Closed
mattphillips opened this issue Nov 9, 2017 · 12 comments
Closed

New matcher: .toHaveBeenCalledBefore(mock) #98

mattphillips opened this issue Nov 9, 2017 · 12 comments

Comments

@mattphillips
Copy link
Member

Feature Request

.toHaveBeenCalledBefore(mock)

Use .toHaveBeenCalledBefore when checking if a mock has been called before another mock.

it('calls mock1 before mock2', () => {
  const mock1 = jest.fn();
  const mock2 = jest.fn();

  mock1();
  mock2();
  mock1();

  expect(mock1).toHaveBeenCalledBefore(mock2);
});
@mattphillips
Copy link
Member Author

taken from jestjs/jest#4402

@mattphillips
Copy link
Member Author

Blocked pending internal timestamp support in Jest: jestjs/jest#4866

@tejasbubane
Copy link
Contributor

I would like to work on this. Will keep an eye on the pending Jest issue.

@tejasbubane
Copy link
Contributor

The PR is merged, should I wait for next release of jest?

@mattphillips
Copy link
Member Author

@tejasbubane you could work on it now but we will have to sync merging/releasing this matcher with the next release of Jest.

We should also probably add a note to the matcher docs that it will only be compatible with >jest@22

@ChrisCinelli
Copy link

ChrisCinelli commented Jan 5, 2018

I am getting:

    TypeError: expect(...).toHaveBeenCalledBefore is not a function

I am using jest@22.0.4 and jest-extended@0.5.0

@mattphillips
Copy link
Member Author

Hey @ChrisCinelli this matcher hasn’t been implemented yet.

@tejasbubane jest@22 has landed now do you still want to work on this? If not I can look into getting it added tomorrow 😄

@ChrisCinelli
Copy link

Yes, I found out.

But I have bad news:

        console.log(setup.mock.timestamps);
        console.log(middleware.mock.timestamps);

Yield to:

  console.log lib/middleware.spec.js:12
    [ 1515112206835 ]

  console.log lib/middleware.spec.js:13
    [ 1515112206835 ]

@ChrisCinelli
Copy link

ChrisCinelli commented Jan 5, 2018

To implement .toHaveBeenCalledBefore we may need a global counter incremented at every call to an instance of a jest.fn() and saving the current value in something likemyFunc.mock.callOrder (or jasmine call it invocationOrder). But this will require another change in Jest.

@mattphillips
Copy link
Member Author

@tejasbubane @ChrisCinelli I've added and published this matcher in v0.6.0 so I'm going to close this issue.

@ChrisCinelli because of the calls to mocks happening in the same event loop the timestamps are identical - as you described. Because of this for this matcher to work it depends on the mock being asynchronous and ran in a different context. For example:

const timeout = time => () => new Promise(res => setTimeout(() => res()), time);

it('calls mock1 before mock2', async () => {
  const mock1 = jest.fn(timeout(1));
  const mock2 = jest.fn(timeout(1));

  await mock1();
  await mock2();
  await mock1();

  expect(mock1).toHaveBeenCalledBefore(mock2);
});

@benjamin21st
Copy link

Wouldn't it be more scalable to implement an API for .series as opposed to limiting one is called before another?

What if use cases come up for three calls? 1000?

@mattphillips
Copy link
Member Author

Hey @benjamin21st feel free to open a new issue and propose the API that you think would be more scalable 😄

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

No branches or pull requests

4 participants