首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >TypeScript中带有proxyquire和sinon的Stub zip

TypeScript中带有proxyquire和sinon的Stub zip
EN

Stack Overflow用户
提问于 2020-11-04 08:24:22
回答 1查看 546关注 0票数 1

我想用jest对类zip.adapter.ts进行单元测试。我尝试了许多不同的方法来模拟/存根adm-zip包,但是没有什么效果。

我第一次尝试T-模拟-进口,但如果我试图模仿adm-zip,它总是失败的。然后,我尝试了西农,但它不是没有存根adm-zip,就是没有存根。我的最后一招是把sinon和丙氧奎尔结合起来,但这似乎也行不通.

有人知道为什么这不管用吗?当测试调用unzip方法时,其中的代码仍然使用实际的adm-zip实现.

(我知道单元测试没有多大意义,因为一切都是被嘲笑的,但我必须这样做,因为测试覆盖率规则是我无法更改的。)

zip.adapter.ts

代码语言:javascript
复制
import * as admZip from 'adm-zip';

export class ZipAdapter {
    constructor() {}

    unzip(zip: Buffer, path: string) {
        const unzip = new admZip(zip);
        unzip.extractAllTo(path, true);
    }
}

zip.adapter.spec.ts

代码语言:javascript
复制
import * as sinon from 'sinon';
import { ZipAdapter } from './zip.adapter';
import * as proxyquire from 'proxyquire';

describe('Zip Adapter', () => {
    let zipAdapter: ZipAdapter;

    beforeEach(() => {
        const admZipInstance = { extractAllTo: sinon.stub() };
        const admZipStub = sinon.stub().callsFake(() => admZipInstance);
        const moduleStub = proxyquire('./zip.adapter.ts', { 'adm-zip': admZipStub });

        zipAdapter = new moduleStub.ZipAdapter();
    });

    it('should be defined', () => {
        expect(zipAdapter).toBeDefined();
    });

    it('should have called extractAllTo', () => {
        zipAdapter.unzip(Buffer.from(''), 'test');
    });
});

更新:

我让我的测试和Jest一起工作,但前提是我需要()我的模块。如果我在使用导入时没有使用require(),那么模拟就不能工作。是否有可能摆脱require()而只使用导入?

代码语言:javascript
复制
import { ZipAdapter } from './zip.adapter';

describe('Zip Adapter', () => {
    let zipAdapter: ZipAdapter;
    let admZipExtractAllMock: jest.Mock<any, any>;

    beforeEach(() => {
        const admZipMock = jest.fn();
        admZipExtractAllMock = jest.fn();
        admZipMock.mockImplementation(() => {
            return { extractAllTo: admZipExtractAllMock };
        });
        jest.mock('adm-zip', () => admZipMock);

        const zipAdapterModule = require('./zip.adapter');
        zipAdapter = new zipAdapterModule.ZipAdapter();
    });

    it('should be defined', () => {
        expect(zipAdapter).toBeDefined();
    });

    it('should have called extractAllTo', () => {
        zipAdapter.unzip('unit', 'test');
        expect(admZipExtractAllMock.mock.calls.length).toBe(1);
    });
});
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-11-04 16:44:46

顶级导入仅导入ZipAdapter类型,因此在第一次使用require导入时会对其进行评估。如果在导入后使用jest.mock对其进行模拟,则不会影响导入模块。

如果需要对所有测试进行模拟,则应该在顶层对其进行模拟和导入:

代码语言:javascript
复制
import * as zipAdapterModule from './zip.adapter';

jest.mock('adm-zip', () => {
  let admZipExtractAllMock = jest.fn();
  return {
    __esModule: true,
    admZipExtractAllMock,
    default: jest.fn(() => ({ extractAllTo: admZipExtractAllMock }))
});

顶部的jest.mock悬挂在import上方。admZipExtractAllMock间谍被公开为命名导出,以便能够随时更改实现,最好使用Once方法不影响其他测试。

如果某些测试不需要对其进行模拟,或者Jest间谍API不足以更改实现,则需要使用jest.mock对其进行模拟,并在如OP所示的测试中使用require导入它。在这种情况下,应该添加jest.resetModules以允许重新导入模拟模块。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64676413

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档