簡體   English   中英

用 Jest 中的測試覆蓋抽象 class 方法

[英]Cover abstract class method with tests in Jest

我有抽象的通用服務 class。

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的 all 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"
              }
            );
          });
        });
      });
    });
  });
});

此處查看完整的覆蓋示例

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM