Skip to content

unmock all test doubles after each test #235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 24 commits into from
May 21, 2024
Merged
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
e5eacd0
feat: create unmock
Chemaclass Oct 30, 2023
1af89bb
docs: update changelog and add docs for unmock
Chemaclass Oct 30, 2023
6ad473c
fix: broken pipe
Chemaclass Oct 30, 2023
518bef4
fix: unmock test
Chemaclass Oct 30, 2023
e028e39
refactor: test_successful_unmock
Chemaclass Oct 30, 2023
c846f06
feat: add assert_is_mock
Chemaclass Oct 30, 2023
3c5964d
refactor: src/test_doubles.sh
Chemaclass Oct 30, 2023
c69e7c2
refactor: simplify test_successful_unmock
Chemaclass Oct 30, 2023
9a216c8
feat: allow unmock spy
Chemaclass Oct 30, 2023
354353a
feat: runner::clean_mocks()
Chemaclass Oct 30, 2023
df9de9c
test: test_runner_clean_mocks
Chemaclass Oct 30, 2023
9dc58c4
test: create acceptance/mock_test
Chemaclass Oct 30, 2023
58f0b66
docs: add assert_is_mock to docs
Chemaclass Oct 30, 2023
a3815ca
refactor: rename clean_mocks to clear_mocks
Chemaclass Oct 31, 2023
6b97a40
test: add test_unsuccessful_unmock
Chemaclass Oct 31, 2023
d1dce6b
chore: use clear_mocks()
Chemaclass Oct 31, 2023
7092b56
fix: local expected in is_mock()
Chemaclass May 20, 2024
1e5bce4
refactor: unmock() unset inside for if
Chemaclass May 20, 2024
00e408a
update changelog
Chemaclass May 20, 2024
1f0aa34
feat: remove internal assert mocks functions
Chemaclass May 20, 2024
b7124b7
test: add spies to acceptance/mock_test
Chemaclass May 20, 2024
dbfb433
fix: Declare and assign separately to avoid masking return values
Chemaclass May 20, 2024
699c0e5
docs: update changelog
Chemaclass May 20, 2024
39be998
docs: remove unmock func from docs
Chemaclass May 21, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

- Add multi-invokers; consolidate parameterized-testing documentation
- Add `fail()` function
- Add `unmock()` function
- Remove all test mocks after each test case

## [0.11.0](https://github.com/TypedDevs/bashunit/compare/0.10.1...0.11.0) - 2024-03-02

Expand Down
32 changes: 31 additions & 1 deletion docs/test-doubles.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ When creating tests, you might need to override existing function to be able to

Allows you to override the behavior of a callable.

> You can undo a mock function, to revert it to its previous original behaviour, with `unmock`.

::: code-group
```bash [Example]
function test_example() {
Expand All @@ -25,7 +27,31 @@ Allows you to override the output of a callable.
```bash [Example]
function test_example() {
function code() {
ps a | grep bash
ps a | grep bash
}

mock ps<<EOF
PID TTY TIME CMD
13525 pts/7 00:00:01 bash
24162 pts/7 00:00:00 ps
EOF

assert_equals "13525 pts/7 00:00:01 bash" "$(code)"
}
```
:::

## unmock

> `unmock "function"`

Undo the previous overridden behavior of a callable using mock.

::: code-group
```bash [Example]
function test_example() {
function code() {
ps a | grep bash
}

mock ps<<EOF
Expand All @@ -34,7 +60,11 @@ PID TTY TIME CMD
24162 pts/7 00:00:00 ps
EOF

# At this point, ps will return the mocked value above
assert_equals "13525 pts/7 00:00:01 bash" "$(code)"

# From now on, ps will have the original behaviour again
unmock ps
}
```
:::
Expand Down
10 changes: 9 additions & 1 deletion src/runner.sh
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@ function runner::call_test_functions() {
runner::run_test "$function_name" "$data"
done
else
local multi_invoker=$(helper::get_multi_invoker_function "$function_name" "$script")
local multi_invoker
multi_invoker=$(helper::get_multi_invoker_function "$function_name" "$script")
if [[ -n "${multi_invoker}" ]]; then
helper::execute_function_if_exists "${multi_invoker}"
else
Expand Down Expand Up @@ -163,6 +164,7 @@ function runner::run_test() {
"$function_name" "$@" 2>&1 1>&3

runner::run_tear_down
runner::clear_mocks
state::export_assertions_count
)

Expand Down Expand Up @@ -228,6 +230,12 @@ function runner::run_tear_down() {
helper::execute_function_if_exists 'tear_down'
}

function runner::clear_mocks() {
for i in "${!MOCKED_FUNCTIONS[@]}"; do
unmock "${MOCKED_FUNCTIONS[$i]}"
done
}

function runner::run_tear_down_after_script() {
helper::execute_function_if_exists 'tear_down_after_script'
}
Expand Down
18 changes: 18 additions & 0 deletions src/test_doubles.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,19 @@
#!/bin/bash

declare -a MOCKED_FUNCTIONS=()

function unmock() {
local command=$1

for i in "${!MOCKED_FUNCTIONS[@]}"; do
if [[ "${MOCKED_FUNCTIONS[$i]}" == "$command" ]]; then
unset "MOCKED_FUNCTIONS[$i]"
unset -f "$command"
break
fi
done
}

function mock() {
local command=$1
shift
Expand All @@ -11,6 +25,8 @@ function mock() {
fi

export -f "${command?}"

MOCKED_FUNCTIONS+=("$command")
}

function spy() {
Expand All @@ -24,6 +40,8 @@ function spy() {
eval "function $command() { ${variable}_params=(\"\$*\"); ((${variable}_times++)) || true; }"

export -f "${command?}"

MOCKED_FUNCTIONS+=("$command")
}

function assert_have_been_called() {
Expand Down
19 changes: 19 additions & 0 deletions tests/acceptance/mock_test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/bin/bash

#
# Make sure that the `runner::clear_mocks()` is being called,
# removing the mocks and spies from the first test
#
function test_runner_clear_mocks_first() {
mock ls echo foo
assert_equals "foo" "$(ls)"

spy ps
ps foo bar
assert_have_been_called_times 1 ps
}

function test_runner_clear_mocks_second() {
assert_not_equals "foo" "$(ls)"
assert_have_been_called_times 0 ps
}