diff --git a/doc/development/testing_guide/frontend_testing.md b/doc/development/testing_guide/frontend_testing.md index 0a6f402d5d2..af477f5ab99 100644 --- a/doc/development/testing_guide/frontend_testing.md +++ b/doc/development/testing_guide/frontend_testing.md @@ -126,13 +126,51 @@ it('tests a promise rejection', (done) => { }); ``` -#### Stubbing +#### Stubbing and Mocking -For unit tests, you should stub methods that are unrelated to the current unit you are testing. -If you need to use a prototype method, instantiate an instance of the class and call it there instead of mocking the instance completely. +Jasmine provides useful helpers `spyOn`, `spyOnProperty`, `jasmine.createSpy`, +and `jasmine.createSpyObject` to facilitate replacing methods with dummy +placeholders, and recalling when they are called and the arguments that are +passed to them. These tools should be used liberally, to test for expected +behavior, to mock responses, and to block unwanted side effects (such as a +method that would generate a network request or alter `window.location`). The +documentation for these methods can be found in the [jasmine introduction page](https://jasmine.github.io/2.0/introduction.html#section-Spies). -For integration tests, you should stub methods that will effect the stability of the test if they -execute their original behaviour. i.e. Network requests. +Sometimes you may need to spy on a method that is directly imported by another +module. GitLab has a custom `spyOnDependency` method which utilizes +[babel-plugin-rewire](https://github.com/speedskater/babel-plugin-rewire) to +achieve this. It can be used like so: + +```javascript +// my_module.js +import { visitUrl } from '~/lib/utils/url_utility'; + +export default function doSomething() { + visitUrl('/foo/bar'); +} + +// my_module_spec.js +import doSomething from '~/my_module'; + +describe('my_module', () => { + it('does something', () => { + const visitUrl = spyOnDependency(doSomething, 'visitUrl'); + + doSomething(); + expect(visitUrl).toHaveBeenCalledWith('/foo/bar'); + }); +}); +``` + +Unlike `spyOn`, `spyOnDependency` expects its first parameter to be the default +export of a module who's import you want to stub, rather than an object which +contains a method you wish to stub (if the module does not have a default +export, one is be generated by the babel plugin). The second parameter is the +name of the import you wish to change. The result of the function is a Spy +object which can be treated like any other jasmine spy object. + +Further documentation on the babel rewire pluign API can be found on +[its repository Readme doc](https://github.com/speedskater/babel-plugin-rewire#babel-plugin-rewire). ### Vue.js unit tests