【问题标题】:Can't call .then when mocking axios call inside componentDidMount在 componentDidMount 中模拟 axios 调用时无法调用 .then
【发布时间】:2019-03-18 21:40:14
【问题描述】:

我正在尝试在模拟 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 是一个 void 方法,但我不确定为什么像 this 这样的教程会这样做。最好只是忽略这种模式吗?

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

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

更大的问题是:在单元测试中模拟 Axios 是否是上述任何一种好的模式?还是我应该只依赖axios-mock-adapter 之类的东西?

【问题讨论】:

  • componentDidMount 正在返回 undefined - 看到该函数没有返回,这就是问题
  • 见stackoverflow.com/a/52767973/3731501。这是同样的问题。你没有承诺链,所以你将无法有效地测试它。至于 axios-mock-adapter,你可以用它来模拟 Axios,因为这就是它的用途。

标签: javascript reactjs typescript unit-testing axios


【解决方案1】:

只需在axios_with_base_url 之前添加return 即可生成promise

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-05-22
    • 2020-06-02
    • 2019-06-30
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 2019-12-06
    • 1970-01-01
    相关资源
    最近更新 更多