在 bash 中测试时是否可以模拟“命令”?

问题描述 投票:0回答:1

我的一个脚本正在尝试确定出现错误时是否安装了所有依赖项。为了做到这一点,我使用内置的

command
。让我们假设我能想到的最有限的版本(我们称之为
script_to_test.sh

command -v pdfgrep
return $?

现在我有一个 bats-core 测试文件

test.sh
:

setup() {
  # See https://bats-core.readthedocs.io/en/stable/tutorial.html
  load 'test_helper/bats-support/load'
  load 'test_helper/bats-assert/load'
  # See https://github.com/buildkite-plugins/bats-mock
  load 'test_helper/mocks/stub'
  DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
  PATH="$DIR/..:$PATH"
}

@test "Test mocking built-ins" {
  stub command \
    "-v pdfgrep : exit 17"
  run script_to_test.sh
  unstub command
  assert_failure 17
}

当我运行它时,我得到:

`unstub command' failed

这是因为存根的

command
从未被调用过。
甚至可以存根内置函数吗? 如何测试依赖于环境的脚本行为?

bash shell unit-testing mocking bats-core
1个回答
0
投票

据我所知,这是不可能的,因为内置命令是 shell 本身的一部分,并且不能轻易替换或存根!但也许我可以用另一种方法使用示例向您解释它,在我的场景中,您可以创建一个封装函数或脚本来封装内置命令的行为,而不是直接依赖内置命令,然后,您可以在测试中存根或模拟此包装函数/脚本,例如,当您使用 Bats 运行

test.sh
时,它将执行名为
Test mocking built-ins
的测试用例。因此,我对
check_dependency
函数进行了存根,以模拟未安装
pdfgrep
且测试预计脚本会失败并退出代码为
1

的场景

让我告诉你如何做:

script_to_test.sh:

#!/bin/bash

check_dependency() {
  command -v "$1" >/dev/null 2>&1
  return $?
}

check_dependency pdfgrep
return $?

测试.sh:

setup() {
  load 'test_helper/bats-support/load'
  load 'test_helper/bats-assert/load'
  load 'test_helper/mocks/stub'
  DIR="$( cd "$( dirname "$BATS_TEST_FILENAME" )" >/dev/null 2>&1 && pwd )"
  PATH="$DIR/..:$PATH"
}

@test "Test mocking built-ins" {
  stub check_dependency \
    "pdfgrep : return 1"
  run script_to_test.sh
  unstub check_dependency
  assert_failure 1
}
© www.soinside.com 2019 - 2024. All rights reserved.