BATS - 如何强制检查程序是否存在失败?

BATS - How to force a check for existence of a program to fail?

我有一个函数可以检查文件是否存在以及它是否可执行。

is_command() {
  [[ -x "$(command -v "" 2> /dev/null)" ]] && return 0
  return 1
}

我有一个脚本需要 dos2unix

is_command 'dos2unix' || { echo 'dos2unix is required'; exit 1}

由于 dos2unix 安装在 /usr/bin 中,我不能只从 PATH 中删除安装路径。我也不想(也不能)暂时重命名实际的 dos2unix 程序。

我尝试在 BASH_CMDS 中设置一个条目,它在命令行中起作用:

$ hash -r ; BASH_CMDS['dos2unix']='/no/such/dir/dos2unix' ; [[ -x "$(command -v dos2unix 2> /dev/null)" ]] ; echo $?
1

但是这个测试不起作用。 assert_output 不匹配(它是程序后面的用法消息)。

 @test 'dos2unix does not exist' {
   hash -r
   BASH_CMDS['dos2unix']='/no/such/dir/dos2unix'
   note "dos2unix: $(command -v dos2unix)"
   run ds
   assert_failure
   assert_output 'dos2unix is required'
 }

我怎样才能完成这项工作?为什么这不起作用?

编辑: 使 assert_output 匹配生成的错误。

假设您的 file-under-test 看起来像这样:

#!/usr/bin/env bash

ds() {

    is_command() {
      [[ -x "$("${command}" -v "" 2> /dev/null)" ]] && return 0
      return 1
    }

    is_command 'dos2unix' || { echo 'dos2unix is required'; exit 1; }

    exit 0;
}

您必须以某种方式将此代码“加载”到您的测试中才能 运行。

大多数情况下,BATS 的load 功能用于此。然而,这个(或类似的设置)混淆了 BASH_CMDS.

的范围

这可以通过从全局范围获取文件来解决:

#!/usr/bin/env bats

source "${BATS_TEST_DIRNAME}/ds.sh" # <-- This part is important

@test 'dos2unix does not exist' {
    hash -r

    BASH_CMDS['dos2unix']='/no/such/dir/dos2unix'

    run ds

   assert_failure
   assert_output 'dos2unix is required'
}

当我运行你的原代码时,确实失败了。使用 source,我的测试通过了。

如果这不能解决您的问题,其他事情可能(也)正在发生...