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

Add documentation related to auto-mocking #8099

Merged
merged 14 commits into from Mar 18, 2019
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -13,6 +13,7 @@

### Chore & Maintenance

- `[*]` Add documentation and tests related to auto-mocking ([#8086](https://github.com/facebook/jest/pull/8099))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move this up under master?

(Might have to merge in master or rebase first)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Synced with upstream master and moved the changelog line under the master heading. Thanks for the feedback and help with this @SimenB !

- `[*]` Make sure to include `d.ts` files in the tarball when building ([#8086](https://github.com/facebook/jest/pull/8086))

### Performance
Expand Down
93 changes: 93 additions & 0 deletions docs/JestObjectAPI.md
Expand Up @@ -119,6 +119,99 @@ test('implementation created by jest.genMockFromModule', () => {
});
```

This is how `genMockFromModule` will mock the following data types:

#### `Function`

Creates a new [mock function](https://jestjs.io/docs/en/mock-functions.html). The new function has no formal parameters and when called will return `undefined`. This functionality also applies to `async` functions.

#### `Class`

Creates new class. The interface of the original class is maintained, all of the class member functions and properties will be mocked.

#### `Object`

Creates a new deeply cloned object. The object keys are maintained and their values are mocked.

#### `Array`

Creates a new empty array, ignoring the original.

#### `Primitives`

Creates a new property with the same primitive value as the original property.

Example:

```
// example.js
module.exports = {
function: function square(a, b) {
return a * b;
},
asyncFunction: async function asyncSquare(a, b) {
const result = await a * b;
return result;
},
class: new class Bar {
constructor() {
this.array = [1, 2, 3];
}
foo() {}
},
object: {
baz: 'foo',
bar: {
fiz: 1,
buzz: [1, 2, 3],
},
},
array: [1, 2, 3],
number: 123,
string: 'baz',
boolean: true,
symbol: Symbol.for('a.b.c'),
};
```

```js
// __tests__/example.test.js
const example = jest.genMockFromModule('./example');

test('should run example code', () => {
SimenB marked this conversation as resolved.
Show resolved Hide resolved
// creates a new mocked function with no formal arguments.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);

// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);

// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toEqual('Bar');
expect(example.class.foo.name).toEqual('foo');
expect(example.class.array.length).toEqual(0);

// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});

// creates a new empty array, ignoring the original array.
expect(example.array.length).toEqual(0);

// creates a new copy of the original primitive.
expect(example.number).toEqual(123);
expect(example.string).toEqual('baz');
expect(example.boolean).toEqual(true);
expect(example.symbol).toEqual(Symbol.for('a.b.c'));
});
```

### `jest.mock(moduleName, factory, options)`

Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example:
Expand Down
46 changes: 46 additions & 0 deletions packages/jest-mock/src/__tests__/index.test.ts
Expand Up @@ -34,6 +34,7 @@ describe('moduleMocker', () => {
expect(moduleMocker.getMetadata('banana').value).toEqual('banana');
expect(moduleMocker.getMetadata(27).value).toEqual(27);
expect(moduleMocker.getMetadata(false).value).toEqual(false);
expect(moduleMocker.getMetadata(Infinity).value).toEqual(Infinity);
});

it('does not retrieve metadata for arrays', () => {
Expand All @@ -57,6 +58,51 @@ describe('moduleMocker', () => {
expect(metadata.members).toBeUndefined();
expect(metadata.type).toEqual('null');
});

it('retrieves metadata for ES6 classes', () => {
class ClassFooMock {
bar() {}
}
const fooInstance = new ClassFooMock();
const metadata = moduleMocker.getMetadata(fooInstance);
expect(metadata.type).toEqual('object');
expect(metadata.members.constructor.name).toEqual('ClassFooMock');
});

it('retrieves synchronous function metadata', () => {
function functionFooMock() {}
const metadata = moduleMocker.getMetadata(functionFooMock);
expect(metadata.type).toEqual('function');
expect(metadata.name).toEqual('functionFooMock');
});

it('retrieves asynchronous function metadata', () => {
async function asyncFunctionFooMock() {}
const metadata = moduleMocker.getMetadata(asyncFunctionFooMock);
expect(metadata.type).toEqual('function');
expect(metadata.name).toEqual('asyncFunctionFooMock');
});

it("retrieves metadata for object literals and it's members", () => {
const metadata = moduleMocker.getMetadata({
bar: 'two',
foo: 1,
});
expect(metadata.type).toEqual('object');
expect(metadata.members.bar.value).toEqual('two');
expect(metadata.members.bar.type).toEqual('constant');
expect(metadata.members.foo.value).toEqual(1);
expect(metadata.members.foo.type).toEqual('constant');
});

it('retrieves Date object metadata', () => {
const metadata = moduleMocker.getMetadata(Date);
expect(metadata.type).toEqual('function');
expect(metadata.name).toEqual('Date');
expect(metadata.members.now.name).toEqual('now');
expect(metadata.members.parse.name).toEqual('parse');
expect(metadata.members.UTC.name).toEqual('UTC');
});
});

describe('generateFromMetadata', () => {
Expand Down
93 changes: 93 additions & 0 deletions website/versioned_docs/version-22.x/JestObjectAPI.md
Expand Up @@ -173,6 +173,99 @@ test('implementation created by jest.genMockFromModule', () => {
});
```

This is how `genMockFromModule` will mock the following data types:

#### `Function`

Creates a new [mock function](https://jestjs.io/docs/en/mock-functions.html). The new function has no formal parameters and when called will return `undefined`. This functionality also applies to `async` functions.

#### `Class`

Creates new class. The interface of the original class is maintained, all of the class member functions and properties will be mocked.

#### `Object`

Creates a new deeply cloned object. The object keys are maintained and their values are mocked.

#### `Array`

Creates a new empty array, ignoring the original.

#### `Primitives`

Creates a new property with the same primitive value as the original property.

Example:

```
// example.js
module.exports = {
function: function square(a, b) {
return a * b;
},
asyncFunction: async function asyncSquare(a, b) {
const result = await a * b;
return result;
},
class: new class Bar {
constructor() {
this.array = [1, 2, 3];
}
foo() {}
},
object: {
baz: 'foo',
bar: {
fiz: 1,
buzz: [1, 2, 3],
},
},
array: [1, 2, 3],
number: 123,
string: 'baz',
boolean: true,
symbol: Symbol.for('a.b.c'),
};
```

```js
// __tests__/example.test.js
const example = jest.genMockFromModule('./example');

test('should run example code', () => {
// creates a new mocked function with no formal arguments.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);

// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);

// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toEqual('Bar');
expect(example.class.foo.name).toEqual('foo');
expect(example.class.array.length).toEqual(0);

// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});

// creates a new empty array, ignoring the original array.
expect(example.array.length).toEqual(0);

// creates a new copy of the original primitive.
expect(example.number).toEqual(123);
expect(example.string).toEqual('baz');
expect(example.boolean).toEqual(true);
expect(example.symbol).toEqual(Symbol.for('a.b.c'));
});
```

### `jest.mock(moduleName, factory, options)`

Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example:
Expand Down
93 changes: 93 additions & 0 deletions website/versioned_docs/version-23.x/JestObjectAPI.md
Expand Up @@ -174,6 +174,99 @@ test('implementation created by jest.genMockFromModule', () => {
});
```

This is how `genMockFromModule` will mock the following data types:

#### `Function`

Creates a new [mock function](https://jestjs.io/docs/en/mock-functions.html). The new function has no formal parameters and when called will return `undefined`. This functionality also applies to `async` functions.

#### `Class`

Creates new class. The interface of the original class is maintained, all of the class member functions and properties will be mocked.

#### `Object`

Creates a new deeply cloned object. The object keys are maintained and their values are mocked.

#### `Array`

Creates a new empty array, ignoring the original.

#### `Primitives`

Creates a new property with the same primitive value as the original property.

Example:

```
// example.js
module.exports = {
function: function square(a, b) {
return a * b;
},
asyncFunction: async function asyncSquare(a, b) {
const result = await a * b;
return result;
},
class: new class Bar {
constructor() {
this.array = [1, 2, 3];
}
foo() {}
},
object: {
baz: 'foo',
bar: {
fiz: 1,
buzz: [1, 2, 3],
},
},
array: [1, 2, 3],
number: 123,
string: 'baz',
boolean: true,
symbol: Symbol.for('a.b.c'),
};
```

```js
// __tests__/example.test.js
const example = jest.genMockFromModule('./example');

test('should run example code', () => {
// creates a new mocked function with no formal arguments.
expect(example.function.name).toEqual('square');
expect(example.function.length).toEqual(0);

// async functions get the same treatment as standard synchronous functions.
expect(example.asyncFunction.name).toEqual('asyncSquare');
expect(example.asyncFunction.length).toEqual(0);

// creates a new class with the same interface, member functions and properties are mocked.
expect(example.class.constructor.name).toEqual('Bar');
expect(example.class.foo.name).toEqual('foo');
expect(example.class.array.length).toEqual(0);

// creates a deeply cloned version of the original object.
expect(example.object).toEqual({
baz: 'foo',
bar: {
fiz: 1,
buzz: [],
},
});

// creates a new empty array, ignoring the original array.
expect(example.array.length).toEqual(0);

// creates a new copy of the original primitive.
expect(example.number).toEqual(123);
expect(example.string).toEqual('baz');
expect(example.boolean).toEqual(true);
expect(example.symbol).toEqual(Symbol.for('a.b.c'));
});
```

### `jest.mock(moduleName, factory, options)`

Mocks a module with an auto-mocked version when it is being required. `factory` and `options` are optional. For example:
Expand Down