javascript - 在 Jest 中用测试覆盖抽象类方法

标签 javascript typescript jestjs

我有一个抽象的通用服务类。

export default abstract class GenericService<Type> implements CrudService<Type> {
    private readonly modifiedUrl: URL;

    public constructor(url: string) {
        this.modifiedUrl = new URL(url, window.location.href);
    }

    public async get(path?: string, filter?: URLSearchParams): Promise<Type> {
        try {
            if (path) {
                this.modifiedUrl.href += `${path}`;
            }
            addQueryParams(this.modifiedUrl, filter);

            const response = await handleRequest(`${this.modifiedUrl}`, getFetchOptions('GET'));
            const data = await response.json();
            return (await data.data) ? data.data : data;
        } catch (error) {
            throw new Error(`Runtime error: ${error}`);
        }
    }
}

export async function handleRequest(input: RequestInfo, init: RequestInit): Promise<Response> {
    const response = await fetch(input, init);

    if (!response.ok) {
        throw new Error(`Network response was not ok: ${response}`);
    }

    return response;
}

我需要用测试覆盖这个 GenericServiceget 方法。我试过这个:

jest.mock('../../components/crudTable/service/GenericService');
const genericService = GenericService;

export class DummyClass {
    public name: string = '';
}
export class DummyService extends GenericService<DummyClass> {}

describe('Generic Service', () => {
    it('1- spy prototype function', async () => {
        const spy = jest.spyOn(genericService.prototype, 'get');
        await genericService.prototype.get();
        expect(spy).toHaveBeenCalledTimes(1);
    });
    it('2- mock prototype function', async () => {
        const mockFn = jest.fn(genericService.prototype.get);
        await mockFn();
        expect(mockFn).toHaveBeenCalledTimes(1);
    });
    it('3- mock subclass function', async () => {
        const dummyService = new DummyService('test url');
        const mockFn = jest.fn(dummyService.get);
        await mockFn();
        expect(mockFn).toHaveBeenCalledTimes(1);
    });
});

此测试有效,但覆盖率统计表明它仍未被覆盖。 那么如何隐藏GenericService的所有get方法呢?

最佳答案

可以考虑下面的做法

GenericService.spec.js
import GenericSerice from "./GenericService";

class DummyService extends GenericSerice {}

describe("GenericSerice", () => {
  beforeAll(() => {
    global.fetch = jest.fn();
  });

  describe("extended by a class", () => {
    let instance;
    beforeAll(() => {
      instance = new DummyService();
    });

    describe("method get", () => {
      describe("with path given", () => {
        const mockPath = "/pa/th";

        describe("receiving successful response", () => {
          let result;
          const mockData = { key: "mock value" };
          beforeAll(async () => {
            global.fetch.mockClear();
            global.fetch.mockResolvedValue({
              ok: true,
              json: jest.fn().mockResolvedValue(mockData)
            });
            result = await instance.get(mockPath);
          });

          it("should return data", () => {
            expect(result).toEqual(mockData);
          });

          it("should request the correct URL", () => {
            expect(global.fetch).toHaveBeenCalledWith(
              "http://localhost/undefined/pa/th",
              {
                method: "GET"
              }
            );
          });
        });
      });
    });
  });
});

检查full coverage example here

关于javascript - 在 Jest 中用测试覆盖抽象类方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58889386/

相关文章:

reactjs - 在父标记的属性中测试嵌套标记属性

reactjs - Jest - 在 React 中测试模态会出错

javascript - 如果嵌套 div 为空,则隐藏父 Div

javascript - 如何创建顺序图像淡入淡出?

javascript - 在 TypeScript 中输入向后引用

Angular 获取当前事件组件路径

javascript - 未捕获的类型错误 : Cannot read properties of undefined (reading 'deep' ) when upgrade to vue 3. x

javascript - 如何在 Grunt 中将项目变量 config.get() 到任务的 initConfig 中?

javascript - Angular 9 报告打印

javascript - 如何测试抛出异常?