我如何去开玩笑地测试此代码?

时间:2019-09-18 12:13:46

标签: typescript vuejs2 jestjs

我对模拟还很陌生,我理解断言并发现它们很简单。但是,嘲笑让我大吃一惊。我在打字稿中有一个vue项目。问题是,我很困惑,不知道如何测试作为服务类公开的API调用。

我的思想和代码设计

apiClient

我创建了一个名为“ apiClient”的axios实例,因此可以随时使用自定义配置。我已将其存储在项目的根目录下。

服务

我已经在我的服务文件夹中将API的每个端点创建为“服务” 每个服务都是一个包含一堆函数的类,我将使用这些函数来获取所需的数据。

我的问题

  • 我的理解是您想模拟所有依赖关系,所以我需要从我的自定义axios实例开始吗?

  • 我还需要模拟该类吗?

  • 我一般会如何嘲笑?我知道在开发中,最通用的答案是“取决于情况”,但我一直在浏览这些开玩笑的文档,但我发现其中一些不清楚。 (也许是我正在寻求答案)
  • 我需要嘲笑什么?

我的代码

ExampleService.ts

import Approval from '@/interfaces/Approval';
import apiClient from '@/axiosConfig';
import { AxiosResponse } from 'axios';

export default class ExampleService {
    // Approvals
    public async getApprovals(id?: string) {
        if (id != null || id !== undefined) {
            return await apiClient
            .get(`/api//approval/${id}`)
            .then((response: AxiosResponse<Approval>) => {
                return response.data;
            });

        } else {
            return await apiClient
            .get('/api/approval')
            .then((response: AxiosResponse<Approval[]>) => {
                return response.data;
            });
        }
    }

    public async postApproval(approval: Approval) {
        return await apiClient
        .post('/api/approval', approval);
    }

    public async putAppoval(id: string, approval: Approval) {
        return await apiClient
        .put(`/api/approval/${id}`, approval);
    }

    public async deleteApproval(id: string) {
        return await apiClient
        .delete(`/api/approval/${id}`);
    }
}

CustomAxiosInstance.ts

import axios, { AxiosResponse } from 'axios';
const apiClient = axios.create({
    baseURL: `${process.env.VUE_APP_ROOT_API}`,
});

export default apiClient;

我的期望

我会喜欢一些我如何模拟的示例代码,以及对为什么选择执行选择的方法的一些解释。请也批评我的代码。我只想改善。

1 个答案:

答案 0 :(得分:1)

此类的单元测试与Vue.js无关,这是解决方案的文件夹结构:

├── ExampleService.ts
├── __tests__
│   └── ExampleService.spec.ts
├── axiosConfig.ts
└── interfaces
    └── Approval.ts

2 directories, 4 files

单元测试ExampleService.spec.ts

import ExampleService from '../ExampleService';
import axios, { AxiosResponse } from 'axios';

jest.mock('axios', () => {
  return {
    create: jest.fn().mockReturnThis(),
    get: jest.fn()
  };
});

const exampleService = new ExampleService();

describe('ExampleService', () => {
  beforeEach(() => {
    (axios.create().get as jest.MockedFunction<typeof axios.get>).mockReset();
  });

  describe('#getApprovals', () => {
    const mockedResponse: AxiosResponse = {
      data: 'mocked data',
      status: 200,
      statusText: 'ok',
      headers: {},
      config: {}
    };
    it('should get approvals by id correctly', async () => {
      (axios.create().get as jest.MockedFunction<typeof axios.get>).mockResolvedValueOnce(mockedResponse);
      const actualValue = await exampleService.getApprovals('1');
      expect(actualValue).toEqual(mockedResponse.data);
      expect(axios.create().get).toBeCalledWith(`/api/approval/1`);
    });

    it('should get approvals correctly', async () => {
      (axios.create().get as jest.MockedFunction<typeof axios.get>).mockResolvedValueOnce(mockedResponse);
      const actualValue = await exampleService.getApprovals();
      expect(actualValue).toEqual(mockedResponse.data);
      expect(axios.create().get).toBeCalledWith(`/api/approval`);
    });
  });
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/57992553/__tests__/ExampleService.spec.ts (7.041s)
  ExampleService
    #getApprovals
      ✓ should get approvals by id correctly (14ms)
      ✓ should get approvals correctly (3ms)

-------------------|----------|----------|----------|----------|-------------------|
File               |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
-------------------|----------|----------|----------|----------|-------------------|
All files          |    73.91 |    53.85 |    57.14 |    83.33 |                   |
 ExampleService.ts |       70 |    53.85 |    57.14 |       80 |          19,23,27 |
 axiosConfig.ts    |      100 |      100 |      100 |      100 |                   |
-------------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       2 passed, 2 total
Snapshots:   0 total
Time:        8.532s

我只测试getApprovals方法,您可以用相同的方式测试其他方法。

基于以下条件的单元测试

"jest": "^24.8.0",
"@types/jest": "^24.0.17",

以下是完整的演示:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/57992553