gpt4 book ai didi

javascript - 如何使用 Jest 模拟和测试包装模块函数的方法?

转载 作者:行者123 更新时间:2023-12-02 21:58:29 25 4
gpt4 key购买 nike

我编写了一个使用 pushover-notifications 模块通过 Pushover 发送通知的函数。看起来如下:

const Push = require('pushover-notifications')

const sendPushoverNotification = (message) => {
const p = new Push({
user: process.env.PUSHOVER_USER_KEY,
token: process.env.PUSHOVER_AUTH_TOKEN,
onerror: (error) => {} // Needs to be specified since this error cannot be caught in the p.send block.
})

const msg = {
// These values correspond to the parameters for msg are detailed on https://pushover.net/api
// 'message' is required. All other values are optional.
message, // Required.
title: 'Title',
sound: 'pushover',
priority: 1
}

p.send(msg, (error, result) => {
if (error) {
console.error('[Pushover] An error occurred.')
console.error(error)
}

if (JSON.parse(result).status === 1) { // Status 1 means push was sent successfully.
console.log('[Pushover] Push notification sent.')
} else {
console.error('[Pushover] An error occurred.')
console.error(result)
}
})
}

module.exports = sendPushoverNotification

我想模拟 p.send(msg, (error, result) ,以便触发其下面的代码块,从而记录 [Pushover] 发生错误。[Pushover] 已发送推送通知。

在一个名为 tests/__mocks__/pushover-notifications.js 的文件中,使用以下代码模拟模块,我有:

function Pushover() {

}

Pushover.prototype.send = () => {
console.log('Message sent')
}

module.exports = {
Pushover
}

tests/send-pushover-notification.test.js下:

const sendPushoverNotification = require('../../src/send-pushover-notification')

test('Should send Pushover message', () => {
sendPushoverNotification('message')
})

我收到的错误来 self 发布的第一 block 代码:

TypeError: Push is not a constructor

2 |
3 | const sendPushoverNotification = (message) => {
> 4 | const p = new Push({

最佳答案

您可以使用jest.mock(moduleName, factory, options)模拟 pushover-notifications 模块。

例如

index.js:

const Push = require('pushover-notifications');

const sendPushoverNotification = (message) => {
const p = new Push({
user: process.env.PUSHOVER_USER_KEY,
token: process.env.PUSHOVER_AUTH_TOKEN,
onerror: (error) => {},
});

const msg = {
message,
title: 'Title',
sound: 'pushover',
priority: 1,
};

p.send(msg, (error, result) => {
if (error) {
console.error('[Pushover] An error occurred.');
console.error(error);
return;
}

if (JSON.parse(result).status === 1) {
console.log('[Pushover] Push notification sent.');
} else {
console.error('[Pushover] An error occurred.');
console.error(result);
}
});
};

module.exports = sendPushoverNotification;

index.test.js:

const sendPushoverNotification = require('.');
const Push = require('pushover-notifications');

jest.mock(
'pushover-notifications',
() => {
const mPush = { send: jest.fn() };
return jest.fn(() => mPush);
},
{ virtual: true },
);

describe('59942177', () => {
it('should send notification', () => {
const p = new Push();
const mResult = JSON.stringify({ status: 1 });
p.send.mockImplementationOnce((msg, callback) => {
callback(null, mResult);
});
const logSpy = jest.spyOn(console, 'log');
sendPushoverNotification('message');
expect(Push).toBeCalledWith({ user: undefined, token: undefined, onerror: expect.any(Function) });
expect(p.send).toBeCalledWith(
{ message: 'message', title: 'Title', sound: 'pushover', priority: 1 },
expect.any(Function),
);
expect(logSpy).toBeCalledWith('[Pushover] Push notification sent.');
});

it('should handle error if status is not equal 1', () => {
const p = new Push();
const mResult = JSON.stringify({ status: 2 });
p.send.mockImplementationOnce((msg, callback) => {
callback(null, mResult);
});
const errorLogSpy = jest.spyOn(console, 'error');
sendPushoverNotification('message');
expect(Push).toBeCalledWith({ user: undefined, token: undefined, onerror: expect.any(Function) });
expect(p.send).toBeCalledWith(
{ message: 'message', title: 'Title', sound: 'pushover', priority: 1 },
expect.any(Function),
);
expect(errorLogSpy).toBeCalledWith('[Pushover] An error occurred.');
expect(errorLogSpy).toBeCalledWith(mResult);
});

it('should handle error if push failure', () => {
const p = new Push();
const mError = new Error('network error');
p.send.mockImplementationOnce((msg, callback) => {
callback(mError);
});
const errorLogSpy = jest.spyOn(console, 'error');
sendPushoverNotification('message');
expect(Push).toBeCalledWith({ user: undefined, token: undefined, onerror: expect.any(Function) });
expect(p.send).toBeCalledWith(
{ message: 'message', title: 'Title', sound: 'pushover', priority: 1 },
expect.any(Function),
);
expect(errorLogSpy).toBeCalledWith('[Pushover] An error occurred.');
expect(errorLogSpy).toBeCalledWith(mError);
});
});

带有覆盖率报告的单元测试结果:

 PASS  src/stackoverflow/59942177/index.test.js
59942177
✓ should send notification (16ms)
✓ should handle error if status is not equal 1 (2ms)
✓ should handle error if push failure (5ms)

console.log node_modules/jest-mock/build/index.js:860
[Pushover] Push notification sent.

console.error node_modules/jest-mock/build/index.js:860
[Pushover] An error occurred.

console.error node_modules/jest-mock/build/index.js:860
{"status":2}

console.error node_modules/jest-mock/build/index.js:860
[Pushover] An error occurred.

console.error node_modules/jest-mock/build/index.js:860
Error: network error
at Object.it (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/59942177/index.test.js:49:20)
at Object.asyncJestTest (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
at resolve (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
at new Promise (<anonymous>)
at mapper (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:26:19)
at promise.then (/Users/ldu020/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:73:41)
at process._tickCallback (internal/process/next_tick.js:68:7)

----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 66.67 | 100 | |
index.js | 100 | 100 | 66.67 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 3 passed, 3 total
Snapshots: 0 total
Time: 5.033s, estimated 10s

源代码:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59942177

关于javascript - 如何使用 Jest 模拟和测试包装模块函数的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59942177/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com