javascript - 如何在类中用 Jest 模拟节点模块?

标签 javascript typescript unit-testing jestjs

我需要在类中模拟 DNS 节点模块,但我不确定如何执行此操作,因为它包含在类中。这是该类的示例...

import { lookup } from 'dns';

class Foo {
    // ...
    protected async _bar(IP: string) {
        // I want to mock "lookup"
        await new Promise<undefined>((resolve, reject) => {
            lookup(IP, (err, addr) => {
                if (err) reject(new Error('DNS Lookup failed for IP_ADDR ' + IP));

                resolve();
            });
        });

        // If dns found then return true
        return true;
    }
    // ...
}

我想创建一个测试文件foo.spec.ts,其中包含类似于以下内容的测试:

import { Foo } from './Foo';

describe('Foo', () => {
    it('Bar Method returns true on success', () => {
        const test = new Foo();

        expect(test._bar('192.168.1.1')).resolves.toBeTruthy();
    });
});

鉴于类定义位于与测试本身不同的单独文件中,我不确定如何在类 Foo 中模拟 lookup 调用。

如有任何帮助,我们将不胜感激!

最佳答案

您使用lookup的方式将不起作用,因为它不返回Promise...

...但您可以使用 util.promisify 将其转换为返回 Promise 的版本.

代码最终看起来像这样:

import { lookup as originalLookup } from 'dns';  // <= import original lookup...
import { promisify } from 'util';
const lookup = promisify(originalLookup);  // <= ...and promisify it

export class Foo {
  async _bar(IP: string) {
    await lookup(IP).catch(err => { throw new Error('Failed'); });
    return true;
  }
}

然后,您可以使用 jest.mock 在测试中模拟 lookup,如下所示:

import { Foo } from './Foo';

jest.mock('dns', () => ({
  lookup: (hostname, callback) => {
    hostname === 'example.com' ? callback() : callback('error');
  }
}))

describe('Foo', () => {
  it('Bar Method returns true on success', async () => {
    const test = new Foo();
    await expect(test._bar('example.com')).resolves.toBeTruthy();  // Success!
    await expect(test._bar('something else')).rejects.toThrowError('Failed');  // Success!
  });
});

请注意,由于调用 jest.mock,因此需要使用 jest.mock (而不是类似 jest.spyOn 的东西)创建模拟> 被吊起并先跑。模拟需要在导入 Foo.js 之前就位,因为它所做的第一件事是创建并存储 promise 的 lookup

关于javascript - 如何在类中用 Jest 模拟节点模块?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57757898/

相关文章:

javascript - 如何将字符串转换为 unicode 字符?

javascript - 如何配置 karma 以便 typescript 源文件是可调试的

javascript - Angular:页面标题服务在导航上仍会发生变化

javascript - 使用 ajax 调用更改 dataTable 列数量

javascript - typescript |与端点的接口(interface)

java - Mockito - 是否有 "value not in List"的匹配器?

ruby-on-rails - 测试委托(delegate)给另一个对象的方法

javascript - 如何模拟用 jest.mock 模拟的类的实例方法?

移动网络的 JavaScript 事件?

javascript - Angular2 在第一次点击后删除点击事件绑定(bind)