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

Rename jest.mock to jest.stub #7592

Closed
yatki opened this issue Jan 9, 2019 · 12 comments
Closed

Rename jest.mock to jest.stub #7592

yatki opened this issue Jan 9, 2019 · 12 comments

Comments

@yatki
Copy link

yatki commented Jan 9, 2019

🚀 Feature Proposal

It would be better to rename jest.mock to jest.stub, because actually what it is doing is stubbing the objects. It doesn't have pre-programmed expectations like mocks have.

Motivation

I love jest and using it for a quite while now. But jest.mock doesn't do what mocks do and that naming bothers me a little bit. I did a lot of research about testing and noticed that we are often using the term mock wrong in js community.

I started my research based on this article but almost all articles I've read confirm this statement: https://martinfowler.com/articles/mocksArentStubs.html

I know it's a major change and I don't know if you already considered this and wanted to go with the term mock because it's more often used, however I think renaming it would bring value by avoiding confusions like I had.

Example

Here some of the documents that I've came across.

Pitch

This is a change to an existing Jest feature.

@SimenB
Copy link
Member

SimenB commented Jan 9, 2019

We have jest.mock('thing', factory), there stub would be wrong. Not sure if it's worth having 2 APIs?

@yatki
Copy link
Author

yatki commented Jan 9, 2019

Hmm I'm not sure if there stub would be that wrong because we would still use the factory to return jest.fn() or an intercepted module object. And I am not sure if we would define the assertions in the factory?

@jeysal
Copy link
Contributor

jeysal commented Jan 9, 2019

I think you may be interpreting "pre-programmed expectations" too narrowly. I don't think it requires the expectations to be defined "before the call happens at runtime" or "above the call in the source code" or something like that. I believe it means that we "pre-program" the expectations when writing the test, so it can still be a mock if the expectation is below the usage of the mock:

const mock = jest.fn();
mock(42); // happens somewhere in the SUT
expect(mock).toHaveBeenCalledWith(42);

I'm happy to be corrected though if you can link me to some literature that is more explicit about this.

@thymikee
Copy link
Collaborator

thymikee commented Jan 9, 2019

The whole "mock"/"stub"/"spy" stuff was very off-putting at the very beginning when I started testing because it's so hard to find a right answer to which is which (or was at the time; MS article tries really well to fix it, which is great). I still see no added value to differentiate that.

In Jest I see mock as a Fake (according to Microsoft nomenclature) because it's very expressive and generic and I'm happy with that. I'd rather consider changing mock to fake and left users to choose which is mock which is stub (who cares tho?), but anyway that would be pretty breaking and I'm against the change, at least in a foreseeable future.

EDIT:
Once we settle down on which is more appropriate, we could, however, introduce aliases and promote new APIs, and eventually drop old syntax.

@SimenB
Copy link
Member

SimenB commented Jan 9, 2019

FWIW sinon merged spies and stubs into fakes in v5: https://sinonjs.org/releases/latest/fakes/

@yatki
Copy link
Author

yatki commented Jan 9, 2019

@jeysal In general practice, mocks have sort of a verification method and you call it after defining the expectations (see mock.verify() line here: https://sinonjs.org/releases/v7.2.2/mocks/) Also you may wanna take a look the links in example section for further references. In the example you gave, you simply do your assertion inside the tests and you are using a stub which is totally fine, but I wouldn't consider that example as a mock example.

@thymikee after reading your comment, now I also think using fake and leaving interpretation to user makes much more sense and it's a better for general use I suppose. But then we need to think about what to do with spyOn. Also, i would insist fake still wouldn't be a mock tho :)

And I also think introducing alternative API and deprecating old ones with upcoming releases is a good way to go. Thanks for elaborating the idea.

@SimenB
Copy link
Member

SimenB commented Jan 9, 2019

A bit related to #6180 if we wanna mess with the overall API anyways, /cc @mattphillips @rickhanlonii

@jeysal
Copy link
Contributor

jeysal commented Jan 9, 2019

@jeysal In general practice, mocks have sort of a verification method and you call it after defining the expectations (see mock.verify() line here: sinonjs.org/releases/v7.2.2/mocks) Also you may wanna take a look the links in example section for further references. In the example you gave, you simply do your assertion inside the tests and you are using a stub which is totally fine, but I wouldn't consider that example as a mock example.

Sure, I am aware that a verify method is a common pattern for mocks, but I disagree that it is what distinguishes them from stubs.
The difference between the approach of Sinon (and most others)

fn should be called once with argument 42.
do stuff.
verify that expected call on fn occurred.

and the approach of Jest

do stuff.
verify that fn has been called once with argument 42.

is IMO a very minor detail.

What distinguishes them from stubs is that they perform assertions on the calls that have occurred on them, while stubs exist to provide canned return values.
jest.fn()s support both types of usage.

@yatki
Copy link
Author

yatki commented Jan 10, 2019

I'm using jest for quite some time now and I also didn't care about it. I just read the jest's official documentation and started writing my tests.

But I recently gave a presentation about testing and in that tried to explain the terminology, and then of course, I suggested to use jest being my favourite test runner at the moment. But then jest.mock API created confusion between some of the listeners because I defined mocks based on what I've read in most articles.

@jeysal I totally understand your argument and it is a minor detail, but it's a detail and seems like it doesn't fit with the literature. And definitely, I'm not an expert on this, I just spent quite some time with testing and read some, and as you said my understanding can be wrong. I'm aware that I'm suggesting this change to the developers who created the most popular testing framework existing at the moment. It's up to them to follow the old terminology or set the new ones.

The thing I care about is Javascript always had issues with standardisation. By now we are in much better shape but we still need to make progress.

I was inspired by Denis Radin's question "Would you get on a plane if it uses Javascript?" in this talk Denis Radin: Applying NASA coding standards to JavaScript | JSConf EU 2017
. And since then I'm trying to be more careful on following community standards. All I want is to see more unified JS community and I just wanted to raise my concern on this :)

@github-actions
Copy link

This issue is stale because it has been open for 1 year with no activity. Remove stale label or comment or this will be closed in 14 days.

@github-actions github-actions bot added the Stale label Feb 25, 2022
@github-actions
Copy link

This issue was closed because it has been stalled for 7 days with no activity. Please open a new issue if the issue is still relevant, linking to this one.

@github-actions
Copy link

github-actions bot commented May 2, 2022

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.
Please note this issue tracker is not a help forum. We recommend using StackOverflow or our discord channel for questions.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 2, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants