如何测试节点文件,在生成函数时收到 'EACCES' 错误

How to test an node file, receiving an 'EACCES' error when spawning the function

创建 CLI 时,我想测试我的功能。为此,我正在使用模块 child_process.

const path = require('path');
const { execFile } = require('child_process');

describe('cli test', () => {
  test('thing', () => {

    const myCli = execFile(
      `${path.resolve(__dirname, '..')}/cli.js`, ['--foo', 'Bar'],
      (err, stdout, stderr) => {
      if (err) {
        console.log('err: ', err);
      }
    });
});

但这会产生以下错误:

Attempted to log "err:  { Error: spawn /projects/cli/src/cli.js EACCES
        at Process.ChildProcess._handle.onexit (internal/child_process.js:240:19)
        at onErrorNT (internal/child_process.js:415:16)
        at process._tickCallback (internal/process/next_tick.js:63:19)
      errno: 'EACCES',
      code: 'EACCES',

运行 这个脚本直接在终端中通过命令:$ node cli.js --foo Bar 完美运行。

现在建议 chmod +x <file> 该文件 ()。但是测试也应该在 CI 和另一台提取 Git 存储库的计算机上工作。

有什么想法吗?

据我所知,git 实际上跟踪文件的可执行位。正如本文所指出的,有一些事情需要考虑:https://medium.com/@tahteche/how-git-treats-changes-in-file-permissions-f71874ca239d

另一种解决方案是不依赖 ./ 执行语法(这需要为相应文件打开可执行位),而是显式使用 shell 命令:

const path = require('path');
const { execFile } = require('child_process');

describe('cli test', () => {
  test('thing', () => {

    const myCli = execFile(
      `sh ${path.resolve(__dirname, '..')}/cli.js`, ['--foo', 'Bar'],
      (err, stdout, stderr) => {
      if (err) {
        console.log('err: ', err);
      }
    });
});

注意我添加到您的代码中的 sh 前缀,这样您就可以执行 sh 命令(它应该在您的所有环境中都可用,例如 CI)文件内容,不管文件本身是否可以执行!

我建议使用 fork 而不是 execFile

The child_process.fork() method is a special case of child_process.spawn() used specifically to spawn new Node.js processes.

这将允许您执行 JS 文件而不需要它们是 shell 可执行文件。

我在尝试 运行 命令行 mysql 命令时收到来自 child_process.spawn 的 EACCESS -13 错误。

我的 PATH 有问题并更新它以添加 /usr/local/mysql/bin/ 解决了问题。

临时修复是 运行 export PATH=$PATH:/usr/local/mysql/bin/

永久修复是:

  1. 类型:sudo nano /etc/paths
  2. 最后加/usr/local/mysql/bin
  3. Ctrl + X
  4. 输入密钥
  5. 键入 hash -r @ 命令行或关闭终端应用程序并再次打开它

注意:我从一个站点获得了临时修复...我不知道为什么它在 bin 的末尾有一个 / 但所有 mysql 可执行文件似乎在没有它的情况下可用在 /etc/paths 文件中