两个不同的axios模拟实例返回了一个错误,提示axios.default不是一个函数。

huangapple go评论68阅读模式
英文:

2 different instance of axios mock having returning an error of axios.default is not a function

问题

在名为eventController的函数中,有两种不同的方式实现了axios调用。第一种方式如下:

axios.post(
   `${url}/API1`,
   {
      data: 'data for API1'
   }
)

然后第二种方式如下:

await axios({
     method: 'POST',
     url: `${url}/API2`,
     data: {
         data: 'data for API2'
     }
  })

在一个函数或控制器中有两个不同的axios调用。

我被分配了使用Jest和TypeScript来为此编写单元测试,到目前为止我所做的是:

jest.mock('axios', () => ({
   post: jest
      .fn()
      .mockResolvedValueOnce({ status: 200 }) 
}));

it("should work", async () => {
  const req = {body: {
     data: 'data for API'
  }}
  const response = await eventController(req);

  expect(response.status).toBe(200);
});

我使用.post方法来模拟第一个axios调用,但是当使用默认的axios模块进行第二个axios调用时,我收到了以下错误:

TypeError: (0 , axios_1.default) is not a function 

我尝试过以下两种方式,但都似乎不起作用:

方式一:

jest.mock('axios', () => ({
   __esModule: true,
   default: jest.fn(),
   post: jest
      .fn()
      .mockResolvedValueOnce({ status: 200 }) 
}));

方式二:

jest.mock('axios', () => ({
   __esModule: true,
   default: { 
     post: jest
        .fn()
        .mockResolvedValueOnce({ status: 200 })
   },
}));

希望有人能帮助我解决这个问题。这是我目前正在使用的库版本:

  • "jest": "^27.0.6"
  • "babel-jest": "^27.0.6"
  • "axios": "^0.21.4",
  • "@types/jest": "^27.0.0",
  • "ts-jest": "^27.0.4"
英文:

In my function named eventController. An axios call has implemented in two ways
The 1st one is on this code

axios.post(
           `${url}/API1`,
           {
              data:'data for API1'
           }
        )

Then this is the 2nd

 await axios({
     method: 'POST',
     url: `${url}/API2`,
     data: {
         data:'data for API2'
     }
  })

2 different axios calls in one function/controller

I'm assigned in implementing a unit test for this using jest in typescript

So what I did so far is this

jest.mock('axios', () => ({
   post: jest
      .fn()
      .mockResolvedValueOnce({ status: 200 }) 
}));

    it("should work", async () => {
      const req = {body: {
     data: 'data for API'
}}
      const response = await eventController(req);

      expect(response.status).toBe(200);
   });

I mock the 1st axios call with .post method but when doing it w/ the second one using the default axios module I have received this error

  TypeError: (0 , axios_1.default) is not a function 

I've tried to implement this way also but both don't seem to work
This:

    jest.mock('axios', () => ({
   __esModule: true,
   default: jest.fn(),
   post: jest
      .fn()
      .mockResolvedValueOnce({ status: 200 }) 
}));

and this:

jest.mock('axios', () => ({
           __esModule: true,
           default: { 
post: jest
              .fn()
              .mockResolvedValueOnce({ status: 200 })
    },
          
        }));

Hoping someone can help me on this one. This is the versions of the library I'm currently using

  • "jest": "^27.0.6"
  • babel-jest": "^27.0.6"
  • "axios": "^0.21.4",
  • @types/jest": "^27.0.0",
  • "ts-jest": "^27.0.4",

答案1

得分: 0

使用 jest.mock(moduleName, factory, options),并且不传递 factory 参数,让 jest 自动模拟一个模块的版本。此外,没有 __mocks__ 目录。

在模拟后,你需要处理 axios 函数和 axios.get() 方法的TS类型,可以使用类型转换来实现。

注意:我使用一个简单的字符串作为模拟的解析值,这个值不匹配AxiosResponse接口。

示例:

main.ts:

import axios from 'axios';

const url = 'http://localhost:3000';
export async function main() {
  const res1 = await axios.post(`${url}/API1`, {
    data: 'data for API1',
  });
  console.log('res1: ', res1);
  const res2 = await axios({
    method: 'POST',
    url: `${url}/API2`,
    data: {
      data: 'data for API2',
    },
  });
  console.log('res2: ', res2);
}

main.test.ts:

import { main } from './main';
import axios from 'axios';

jest.mock('axios');

const axiosMock = axios as jest.MockedFunction<typeof axios>;
const axiosPostMock = axios.post as jest.MockedFunction<typeof axios.post>;

test('should pass', async () => {
    expect(jest.isMockFunction(axios)).toBe(true);
    expect(jest.isMockFunction(axios.post)).toBe(true);
    axiosPostMock.mockResolvedValueOnce('fake data 1');
    axiosMock.mockResolvedValueOnce('fake data 2' as any);
    await main();
});

测试结果:

 PASS  stackoverflow/76407602/main.test.ts (38.236 s)
  ✓ should pass (48 ms)

  console.log
    res1:  fake data 1

      at stackoverflow/76407602/main.ts:8:11

  console.log
    res2:  fake data 2

      at stackoverflow/76407602/main.ts:16:11

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        41.384 s
英文:

Just use jest.mock(moduleName, factory, options) and without passing the factory argument, let the jest mocks a module with an auto-mocked version. And, there is no __mocks__ directory.

You need to handle the TS types for axios function and axios.get() method after mocking, use type cast to do this.

Note: I use a simple string as the mock resolved value which does not match the AxiosResponse interface.

E.g.

main.ts:

import axios from &#39;axios&#39;;

const url = &#39;http://localhost:3000&#39;;
export async function main() {
  const res1 = await axios.post(`${url}/API1`, {
    data: &#39;data for API1&#39;,
  });
  console.log(&#39;res1: &#39;, res1);
  const res2 = await axios({
    method: &#39;POST&#39;,
    url: `${url}/API2`,
    data: {
      data: &#39;data for API2&#39;,
    },
  });
  console.log(&#39;res2: &#39;, res2);
}

main.test.ts:

import { main } from &#39;./main&#39;;
import axios from &#39;axios&#39;;

jest.mock(&#39;axios&#39;);

const axiosMock = axios as jest.MockedFunction&lt;typeof axios&gt;;
const axiosPostMock = axios.post as jest.MockedFunction&lt;typeof axios.post&gt;;

test(&#39;should pass&#39;, async () =&gt; {
    expect(jest.isMockFunction(axios)).toBe(true);
    expect(jest.isMockFunction(axios.post)).toBe(true);
    axiosPostMock.mockResolvedValueOnce(&#39;fake data 1&#39;);
    axiosMock.mockResolvedValueOnce(&#39;fake data 2&#39; as any);
    await main();
});

Test result:

 PASS  stackoverflow/76407602/main.test.ts (38.236 s)
  ✓ should pass (48 ms)

  console.log
    res1:  fake data 1

      at stackoverflow/76407602/main.ts:8:11

  console.log
    res2:  fake data 2

      at stackoverflow/76407602/main.ts:16:11

Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        41.384 s

huangapple
  • 本文由 发表于 2023年6月5日 22:44:14
  • 转载请务必保留本文链接:https://go.coder-hub.com/76407602.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定