开玩笑手册嘲笑需要新的实例包(Jest manual mocking a package requi

2019-09-30 18:09发布

我试图用Jest人工模拟来模拟一个包的行为X项目中使用。

包的使用X的实际应用程序代码中是如下所示:

// Real.js

import X from '../lib/X.js';


export default class App  {

  ...

  execute() {
    const x = new X(); // creating a new instance of X
    x.doSomething();   // calling someThing() of X
  }

  ...

}

我的玩笑人工模拟模仿的行为X的样子:

global.__test__X = () => ({
  doSomething: jest.fn(async () => console.log('mocked async do something')),
  id: (Math.random() * 1000) % 10,
});

module.exports = global.__test__X;

在我的测试我试图看到X被调用多少次,并使用打击代码什么参数:

jest.mock('../X');
import Real from '../Real';
const X = require('../X');

describe('Testing...', async () => {
  it('DoSomething should print mocked console statement', async () => {
    Real.execute(); // this would internally call X.doSomething()
    const x = new X();
    console.log(x.doSomething.mock.calls); // gives []

  });
});

使用上面,我想检查多少次X被称为,但不能找出我做错了什么,因为mock.calls始终是[] 请注意,这是获得执行模拟我所看到的mocked async do something

Answer 1:

有与jest.mock(” ./ SomeClass的)这样一个完整的解释; 适用于这个问题。 “ES6类,自动模拟” 。 让我们开始吧。

// ./lib/X.js
export default class X {
  constructor () {
    this.id = '1234567890';
  }

  doSomething = () => {
    return 'Original X';
  }
}

请注意,上面的代码从未在测试过程中调用。

这是我们要测试的资源,我的意思是,在这个类中创建该被嘲笑的类或模块对象。 我们想要做一个假版本,而不是原来的。

// Real.js
import X from './lib/X.js';

export default class App  {
  constructor() {
    this.x = new X(); // creating a new instance of X
  }

  execute = () => {
    this.x.doSomething(); // calling someThing() of X
  }
}

接受应作为模拟执行的功能。 使用手动嘲笑(__ __嘲笑文件夹),以嘲笑ES6类,所以我们需要做的是。

// ./__mocks__/lib/X.js
module.exports = jest.fn().mockImplementation(() => {
  return {
    doSomething: jest.fn(() => 'Mocking Original X'),
    id: (Math.random() * 1000) % 10
  }
});

当我们import './lib/X.js'在我们的测试文件,现在,为了测试这个方法没有实际击中库(以及因此形成缓慢和脆弱的测试),我们立即使用模拟的'./lib/X.js'模块。

// Real.test.js
import X from './lib/X.js';
import Real from './Real';

jest.mock('./lib/X.js'); // // X module is now a mock constructor

describe('Testing', async () => {
  beforeEach(() => {
    // Clear all instances and calls to constructor and all methods:
    X.mockClear();
  });


  it('DoSomething should print mocked correct statement', async () => {
    // Ensure our mockClear() is clearing out previous calls to the constructor
    expect(X).not.toHaveBeenCalled(); 

    const real = new Real();
    expect(X).toHaveBeenCalledTimes(1); // Constructor has been called X.js

    real.execute();

    // mock.instances is available with automatic mocks:
    const mockXInstance = X.mock.instances[0];
    const mockDoSomething = mockXInstance.doSomething;
    expect(mockDoSomething).toHaveBeenCalledTimes(1);
    expect(mockDoSomething.mock.calls[0][0]).toEqual('Mocking Original X');
  });
});

也许这是不够的回答,至少这说明了在类似案件中如何模拟作品



文章来源: Jest manual mocking a package requiring new instance