如何模拟或存根处理.argv



如何模拟或存根process.argv以便它可以返回特定的参数?

我试过这样使用Sinon.js:

beforeEach(
() => {
sandbox.stub(
process.argv.slice(2)[0], 'C:\home\project\assignment'
).value('--local');
}
);
afterEach(
() => {
sandbox.restore();
}
);
test(
'it replace value of node argument',
() => {
assert(process.argv.slice(2)[0], '--local');
}
);

但我一直收到一个错误,说尝试截断undefined的属性'C:\home\project\assignment'

您可以重新绑定process.argv(参见修改节点进程环境或参数运行时(:

import assert from 'node:assert/strict';
import test from 'node:test';
test.describe(
() => {
const originalArgv = process.argv;
test.afterEach(
() => {
process.argv = originalArgv;
}
);
test.test(
() => {
process.argv = process.argv.slice(0, 1).concat(['--local']);
assert.equal(process.argv[1], '--local');
}
);
}
);

如果您喜欢在测试中修改process.argv,而不是像@LinDu的答案中那样重新绑定,您可以通过使每个测试在其原始process.argv的*浅拷贝上运行来保存和恢复process.argv,这样测试就不会相互影响:

import assert from 'node:assert/strict';
import test from 'node:test';
test.describe(
() => {
const originalArgv = process.argv;
test.beforeEach(
() => {
process.argv = [...originalArgv];  // own shallow copy
}
);
test.test(
() => {
process.argv[1] = '--local';
assert.equal(process.argv[1], '--local');
}
);
}
);

*请注意,在原始process.argv共享浅副本上进行每个测试是不起作用的,因为测试会相互影响:

// THIS CODE IS INCORRECT!
import assert from 'node:assert/strict';
import test from 'node:test';
test.describe(
() => {
const originalArgv = [...process.argv];  // shared shallow copy
test.beforeEach(
() => {
process.argv = originalArgv;
}
);
test.test(
() => {
process.argv[1] = '--local';
assert.equal(process.argv[1], '--local');
}
);
}
);

许多Jest用户会对这个问题嗤之以鼻,所以我在这里用Jest发布答案。自29.x以来,Jest有一个replaceProperty方法。

jest.replaceProperty(process, 'argv', ['what', 'ever', 'you', 'like']);

优点是这种模拟可以还原。