在componentDidMount中模拟axios调用时无法调用.then

时间:2018-10-14 06:41:42

标签: javascript reactjs typescript unit-testing axios

我正在模拟Axios调用时进行单元测试componentDidMount

// src/App.tsx
import axios_with_baseUrl from './axios-instance-with-baseUrl';
...

public componentDidMount() {
    axios_with_baseUrl.get('/data.json')
       .then(resp => this.setState({ stuff }));
}

// src/App.test.tsx
jest.mock('./axios-instance-with-baseUrl', () => {
    return {
       get: jest.fn(() => Promise.resolve(someFakeData))
    };
});

import axios_with_baseUrl from './axios-instance-with-baseUrl';

test('fetches data on componentDidMount', async () => {
    const app = enzyme.shallow(<App />);
    app.instance().componentDidMount()
       .then(() => {
           expect(axios_with_baseUrl.get).toHaveBeenCalled();
       });
});

测试上面的代码时,出现以下错误消息:

TypeError: Cannot read property 'then' of undefined

  26 | test('componentDidMount', async () => {
  27 |   const app = enzyme.shallow(<App />);
> 28 |   app.instance().componentDidMount()
     |   ^
  29 |     .then(() => {

我认为这是有道理的,因为componentDidMount是一个无效方法,但是我不确定为什么像this这样的教程会这样做。最好只是忽略该模式吗?

这是我发现的另一种模式:

await app.instance().componentDidMount();
expect(axios_with_baseUrl.get).toHaveBeenCalled();

更大的问题是:以上两种在单元测试中模拟Axios的良好模式中有哪些?还是我应该依靠axios-mock-adapter之类的东西?

1 个答案:

答案 0 :(得分:0)

只需在return之前添加axios_with_base_url即可制作promise

public componentDidMount() {
    return axios_with_baseUrl.get('/data.json')
       .then(resp => this.setState({ stuff }));
}