The problem that mocks and stubs are intended to solve, is that you usually don't want to really call some methods or dependencies in your test, because:
They are unreliable, like http requests:
If you have a module than display a list of users grabbed from the internet, when you test your module you don't want your test to fail due to bad network connectivity, lack of credentials etc. etc.
They are difficult to set up in your tests:
Some modules or dependencies requires a lot of parameters/setup conditions to be able to be used by the module under test, thus making it difficult and error prone to be tested. By mocking or stubbing such a dependency you can test the logic of the module under test without having to handle the burden of managing the dependency needs.
They have their own tests:
If you're testing a carousel module, which relies on an i18n module, and you have yet tested your i18n module, you don't want to test that it works properly again. You mock it, so you're free to the i18n module setup and dependencies.
They are computationally intense:
Let's say you want to test a react/Angular/Vue... component that display UI dashboard and menus for a web videogame. You absolutely don't want to actually have the game running while you test that the navbar of the game dashboard behaves as expected.
So, while testing, you end up mocking and stubbing a lot of dependencies, should they be functions that perform http calls or structural modules like a flux store or a i18n plugin.
jest.fn()
in particular does this at the level of functions. For instance you're testing a vue component that in its created()
hook calls some method that performs something you don't want to deal with in your test:
maybe it calls an API, mess with local storage or do something computationally intense. So you spy that method placing jest.fn()
in its place, and you just assert that it gets called when it should.