我有一些代码以其回调形式使用节点模块ssh-exec。
const sshExec = require('ssh-exec');
const myCodeThatUsesSshExec = (arg1,arg2,arg3) => new Promise((resolve, reject) => {
sshExec('ls -lh', 'ubuntu@my-remote.com', function (err, stdout, stderr) {
if(err) {
reject(err);
} else if(stderr) {
reject(stderr);
} else {
// process stdout
const results = process stdout into an array...
resolve(results);
}
})
});
我正在尝试测试代码,但无法弄清楚如何模拟回调函数以返回模拟数据。到目前为止,这是我的尝试-
const myCodeThatUsesSshExec = require('./my-code');
jest.mock('ssh-exec');
test('ssh test', async () => {
const resp = `total 268K
-rw-rw-rw- 1 bob bob 369 Jun 12 15:00 Dockerfile
-rw-rw-rw- 1 bob bob 849 Jun 12 14:46 app.js
drwxr-xr-x 1 bob bob 4.0K Jun 12 10:01 bin
-rw-rw-rw- 1 bob bob 49 Jun 15 14:34 jest.config.js`;
// I know this doesn't work, just trying to illustrate what I'm trying to do.
sshExec.mockReturnValue(Promise.resolve(resp));
const received = await myCodeThatUsesSshExec(1,2,3);
expect(received).toEqual(['Dockerfile', 'app.js', 'bin', 'jest.config.js']);
});
如何模拟ssh-exec回调?
答案 0 :(得分:1)
简短的答案是您不要模拟回调,因为这是您要测试的主题的一部分。您当前的测试无效,因为ssh-exec
不返回承诺;它接受并调用回调。通常,双打测试需要匹配其替换对象的接口。
相反,请使用模拟的ssh-exec
来调用 real 回调:
const sshExec = require('ssh-exec');
const myCodeThatUsesSshExec = require('./my-code');
jest.mock('ssh-exec');
test('ssh test', async () => {
const resp = `total 268K
-rw-rw-rw- 1 bob bob 369 Jun 12 15:00 Dockerfile
-rw-rw-rw- 1 bob bob 849 Jun 12 14:46 app.js
drwxr-xr-x 1 bob bob 4.0K Jun 12 10:01 bin
-rw-rw-rw- 1 bob bob 49 Jun 15 14:34 jest.config.js`;
// you can't await here, because it will block until the callback is invoked...
const promise = myCodeThatUsesSshExec(1, 2, 3);
// assert on the call to ssh-exec
expect(sshExec).toHaveBeenCalledWith('ls -lh', 'ubuntu@my-remote.com', expect.any(Function));
// invoke the callback, which is the third argument to the first call
sshExec.mock.calls[0][2](null, resp);
// assert on the result
expect(await promise).toEqual(['Dockerfile', 'app.js', 'bin', 'jest.config.js']);
// or you can remove async from this test case and use:
// expect(promise).resolves.toEqual(['Dockerfile', 'app.js', 'bin', 'jest.config.js']);
});
或者,为ssh-exec
制作自己的包装,使其更适合您的用例:
const sshPromise = (...args) => new Promise((resolve, reject) => {
sshExec(...args, (err, stdout, stderr) => {
if (err) {
reject(err);
} else if (stderr) {
reject(stderr);
} else {
resolve(stdout);
}
});
});
现在,您可以模拟自己拥有的这个更简单的界面,并且原始测试将按预期工作。
它还简化了使用代码:
const myCodeThatUsesSshExec = (arg1, arg2, arg3) => sshPromise('ls -lh', 'ubuntu@my-remote.com')
.then((stdout) => {
// process stdout
const results = process stdout into an array...
return results;
});