Skip to content

Commit

Permalink
Added support for naming mocked functions (#4586)
Browse files Browse the repository at this point in the history
* Added ability to specify a name for mocked functions

* Added integration tests for mock name functionality

* Added unit tests for mock name functionality

* Linting fix

* Switched from snapshot matching to regex matching because the snapshots vary by platform, apparently

* Re-add accidentally removed doc section

* Fix the order of replaced doc section

* Fix test syntax

* Additional unit tests

* Fix linting problems

* Removed functionality of having mock name passed as argument to jest.fn() and only use jest.fn().mockName() to set it

* Linting fix
Remove obsolete unit tests

* Add a test to confirm that mockReset() clears out the mockName() value.

* Updated documentation to note that mockReset() clears out the mockName() value also

* Added tests to ensure mockClear() & mockReset() do not affect mockName() value

* Changed mockName() API to return the current mock name via a separate getMockName() instead of overloading mockName() function to return it when no arguments are passed

* Update MockFunctionAPI.md
  • Loading branch information
gricard authored and cpojer committed Oct 8, 2017
1 parent f19d313 commit efe65d4
Show file tree
Hide file tree
Showing 36 changed files with 503 additions and 18 deletions.
24 changes: 23 additions & 1 deletion docs/en/MockFunctionAPI.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ Mock functions are also known as "spies", because they let you spy on the behavi

## Reference

### `mockFn.getMockName()`
Returns the mock name string set by calling `mockFn.mockName(value)`.

### `mockFn.mock.calls`
An array that represents all calls that have been made into this mock function. Each call is represented by an array of arguments that were passed during the call.

Expand Down Expand Up @@ -55,7 +58,7 @@ Beware that `mockClear` will replace `mockFn.mock`, not just [`mockFn.mock.calls
The [`clearMocks`](configuration.html#clearmocks-boolean) configuration option is available to clear mocks automatically between tests.

### `mockFn.mockReset()`
Resets all information stored in the mock, including any inital implementation given.
Resets all information stored in the mock, including any initial implementation and mock name given.

This is useful when you want to completely restore a mock back to its initial state.

Expand Down Expand Up @@ -138,6 +141,25 @@ console.log(myMockFn(), myMockFn(), myMockFn(), myMockFn());
> 'first call', 'second call', 'default', 'default'
```

### `mockFn.mockName(value)`
Accepts a string to use in test result output in place of "jest.fn()" to indicate which mock function is being referenced.

For example:

```js
const mockFn = jest.fn().mockName('mockedFunction');
// mockFn();
expect(mockFn).toHaveBeenCalled();
```

Will result in this error:
```
expect(mockedFunction).toHaveBeenCalled()
Expected mock function to have been called.
```


### `mockFn.mockReturnThis()`
Just a simple sugar function for:

Expand Down
13 changes: 13 additions & 0 deletions docs/en/MockFunctions.md
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,19 @@ const otherObj = {
};
```

## Mock Names

You can optionally provide a name for your mock functions, which will be displayed instead of "jest.fn()" in test error output. Use this if you want to be able to quickly identify the mock function reporting an error in your test output.

```javascript
const myMockFn = jest.fn()
.mockReturnValue('default')
.mockImplementation(scalar => 42 + scalar)
.mockName('add42');

const myMockFn2 = jest.fn(scalar => 42 + scalar, 'add42');
```

## Custom Matchers

Finally, in order to make it simpler to assert how mock functions have been
Expand Down
67 changes: 67 additions & 0 deletions integration_tests/__tests__/mock_names.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/
'use strict';

const runJest = require('../runJest');

test('suite without mock name, mock called', () => {
const {stderr, status} = runJest('mock-names/without-mock-name');

expect(status).toBe(0);
expect(stderr).toMatch(/PASS/);
});

test('suite without mock name, mock not called', () => {
const {stderr, status} = runJest('mock-names/without-mock-name-not-called');

expect(status).toBe(1);
expect(stderr).toMatch(/expect\(jest\.fn\(\)\)\.toHaveBeenCalled/);
});

test('suite with mock name, expect mock not called', () => {
const {stderr, status} = runJest('mock-names/with-mock-name-not-called-pass');

expect(status).toBe(0);
expect(stderr).toMatch(/PASS/);
});

test('suite with mock name, mock called, expect fail', () => {
const {stderr, status} = runJest('mock-names/with-mock-name-not-called-fail');

expect(status).toBe(1);
expect(stderr).toMatch(/expect\(myMockedFunction\)\.not\.toHaveBeenCalled/);
});

test('suite with mock name, mock called 5 times', () => {
const {stderr, status} = runJest('mock-names/with-mock-name-call-times-pass');

expect(status).toBe(0);
expect(stderr).toMatch(/PASS/);
});

test('suite with mock name, mock not called 5 times, expect fail', () => {
const {stderr, status} = runJest('mock-names/with-mock-name-call-times-fail');

expect(status).toBe(1);
expect(stderr).toMatch(/expect\(myMockedFunction\)\.toHaveBeenCalledTimes/);
});

test('suite with mock name, mock called', () => {
const {stderr, status} = runJest('mock-names/with-mock-name');

expect(status).toBe(0);
expect(stderr).toMatch(/PASS/);
});

test('suite with mock name, mock not called', () => {
const {stderr, status} = runJest('mock-names/with-mock-name-not-called');

expect(status).toBe(1);
expect(stderr).toMatch(/expect\(myMockedFunction\)\.toHaveBeenCalled/);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
// empty mock name should result in default 'jest.fn()' output
const mockFn = jest.fn(importedFn).mockName('');

test('first test', () => {
// mockFn explicitly not called to test error output
expect(mockFn).toHaveBeenCalledTimes(1);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
// empty mock name should result in default 'jest.fn()' output
const mockFn = jest.fn(importedFn).mockName('');

test('first test', () => {
mockFn();
expect(mockFn).toHaveBeenCalledTimes(1);
});
10 changes: 10 additions & 0 deletions integration_tests/mock-names/with-empty-mock-name/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
const mockFn = jest.fn(importedFn).mockName('myMockedFunction');

test('first test', () => {
mockFn();
mockFn();
expect(mockFn).toHaveBeenCalledTimes(5);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
const mockFn = jest.fn(importedFn).mockName('myMockedFunction');

test('first test', () => {
mockFn();
mockFn();
mockFn();
mockFn();
mockFn();
expect(mockFn).toHaveBeenCalledTimes(5);
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
const mockFn = jest.fn(importedFn).mockName('myMockedFunction');

test('first test', () => {
mockFn();
expect(mockFn).not.toHaveBeenCalled();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
const mockFn = jest.fn(importedFn).mockName('myMockedFunction');

test('first test', () => {
// mockFn explicitly not called to test error output
expect(mockFn).not.toHaveBeenCalled();
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

'use strict';

jest.mock('../');
const importedFn = require('../');
const mockFn = jest.fn(importedFn).mockName('myMockedFunction');

test('first test', () => {
// mockFn explicitly not called to test error output
expect(mockFn).toHaveBeenCalledTimes(1);
});
10 changes: 10 additions & 0 deletions integration_tests/mock-names/with-mock-name-not-called/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
/**
* Copyright (c) 2014-present, Facebook, Inc. All rights reserved.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*
* @flow
*/

module.exports = () => {};
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"jest": {
"testEnvironment": "node",
"clearMocks": true
}
}
Loading

0 comments on commit efe65d4

Please sign in to comment.