【问题标题】:Jest - how to mock a Class used by a module?开玩笑 - 如何模拟模块使用的类?
【发布时间】:2020-03-24 23:06:22
【问题描述】:

我有课:

class RequestTimeout {
    constructor(timeoutMilliseconds) {
        this.timeoutMilliseconds = timeoutMilliseconds;
        this.timeoutID = undefined;
    }

    start() {
        return new Promise((resolve, reject) => {
            this.timeoutID = setTimeout(() => reject(new Error(`Request attempt exceeded timeout of ${this.timeoutMilliseconds}`)), this.timeoutMilliseconds);
        });
    }

    clear() {
        if (this.timeoutID) clearTimeout(this.timeoutID);
    }
}

module.exports = RequestTimeout;

这个类在一个模块中使用:

const RequestTimeout = require('./request-timeout');

function Request() {
  ...

  async function withTimeout(request, ms) {
        const timeout = new RequestTimeout(ms);

        return Promise.race([
            request(),
            timeout.start(),
        ])
            .then(
                response => {
                    timeout.clear();
                    return response;
                },
                err => {
                    timeout.clear();
                    throw err;
                }
            );
    }

  ...
}

如何在使用Request 的测试中模拟RequestTimeout?例如:

it('should clear the timeout following a successful response', async () => {
  nock('http://example.com')
    .get('/')
    .reply(200, { example: true });

  const response = await request.get({ ...baseOptions });

  expect(response.example).toEqual(true);
});

【问题讨论】:

    标签: jestjs


    【解决方案1】:

    // 模拟

    let mockGetTimeOutId = jest.fn();
    jest.mock('../request-timeout', () => {
        return jest.fn().mockImplementation((ms) => {
            let timeoutId = undefined;
            return {
                start: () => new Promise((resolve, reject) => {
                    timeoutId = setTimeout(() => reject(), ms);
                }),
                clear: () => mockGetTimeOutId(timeoutId),
            }
        })
    });
    

    // 测试

    it('should clear the timeout following a successful response', async () => {
        nock('http://example.com')
            .get('/')
            .reply(200, { example: true });
    
        expect(mockGetTimeOutId).toHaveBeenCalledTimes(0);
    
        const response = await request.get({ ...baseOptions });
    
        expect(mockGetTimeOutId).toHaveBeenCalledTimes(1);
        expect(response.example).toEqual(true);
    });
    

    【讨论】:

      猜你喜欢
      • 2018-07-25
      • 2020-03-05
      • 1970-01-01
      • 2018-03-02
      • 1970-01-01
      • 1970-01-01
      • 2020-10-20
      • 1970-01-01
      • 2018-05-05
      相关资源
      最近更新 更多