使用Jest模拟组件方法

时间:2017-04-20 09:38:30

标签: reactjs mocking jestjs

我有一个使用fetch与API通信的react组件,它看起来像这样

class Customer extends Component {
  loadCustomer(id) {
    fetch(API + '/customers/' + id)
    .then((response) => response.json())
    .then((js) => {
       this.update(js);
    })
    .catch((error) => {
      console.error(error);
    }
  }
}

我正在尝试像这样编写jest测试

jest.mock(Customer, () => {loadCustomer: jest.fn()});

describe('Customer', () => {
  it('renders customer', async  () => {
    const ret = `
    // sample json from the API
    `
    const result = Promise.resolve(ret);
    const tree = renderer.create(
      <Customer customerId={125}/>
    );
    loadCustomer.mockImplementation(() => result);
    await result;
    expect(tree.toJSON()).toMatchSnapshot();
  });
});

失败
 FAIL  tests/Customer.test.js
  ● Test suite failed to run

    TypeError: Cannot read property 'default' of undefined

      at Object.<anonymous> (tests/Customer.test.js:12:48)

违规线是 jest.mock(Customer, () => {loadCustomer: jest.fn()});

我在这里缺少什么?

修改
如果我将违规行更改为 jest.mock(Customer, () => ({loadCustomer: jest.fn()})); 我得到了

FAIL  tests/Customer.test.js
  ● Test suite failed to run
    TypeError: Cannot read property 'default' of undefined

      at Object.<anonymous> (tests/Customer.test.js:12:48)
      at process._tickCallback (internal/process/next_tick.js:103:7)

修改
如果我像这样嘲笑fetch方法

beforeEach(() => {
  global.fetch = jest.fn().mockImplementation(() => {
    var p = new Promise((resolve, reject) => {
      resolve({
        json: function() {
          return { // some json }
        }
     return p;
    });
  });
});

describe('Customer', () => {
  it('renders customer', async () => {
    const tree = renderer.create(
      <Customer customerId={125}/>
    ).toJSON();
    await tree;
    expect(tree).toMatchSnapshot();
  });
});

然后测试不等待提取完成。

1 个答案:

答案 0 :(得分:0)

模拟fetch时的问题是它返回一个promise,但是你的测试不会等待或返回这个promise,看看这个part of the docs来理解这个问题。

var p
beforeEach(() => {
  var p = Promise.resolve({
    json: () => ({}),
  })
  global.fetch = () => p
});

describe('Customer', () => {
  it('renders customer', async () => {
    const tree = renderer.create(
      <Customer customerId={125} />,
    ).toJSON();
    await p;
    expect(tree).toMatchSnapshot();
  });
});

因此,您需要创建承诺并将其存储在变量中,以便您可以在测试中等待它。