gpt4 book ai didi

mocking - 根据调用函数的次数返回不同的值

转载 作者:行者123 更新时间:2023-12-05 09:37:09 28 4
gpt4 key购买 nike

背景

我在一个使用 Mock 的项目中工作供测试用。但是我需要运行一个特定的场景,其中函数的输出取决于调用该函数的次数。我不认为 Mock 支持这个,所以我试图找到一种方法来进行这个测试。

代码

在这个测试中,我有一个我想模拟的存储模块(它有副作用并且是一个边界)。在测试中,我调用了一个函数 get,它第一次返回 nil,然后我用 save 保存了一些数据,然后我调用了 get再次。

test_with_mock "returns OK when products list is saved into storage", Storage, [],
[
save: fn _table, data -> {:ok, data} end,
get: fn
_table, _seats_number -> {:ok, nil} # first call it returns nil
_table, _seats_number -> {:ok, [1]} # second call should return some data
end
] do
# Arrange
products = [
%{"id" => 1, "gems" => 4},
%{"id" => 3, "gems" => 4},
]
products_table = :products

# Act & Assert
actual = Engine.save_products(products)
expected = {:ok, :list_saved_successfully}

assert actual == expected

# First call to get returns nil because the table is empty.
# Then we save something into it.
assert_called Storage.get(products_table, 4)
assert_called Storage.save(products_table, {4, [1]})

# Second call should return the product previously saved
# But the mock only returns nil
assert_called Storage.get(products_table, 4)
end

这里的问题是,由于没有计数器,我无法根据调用函数的次数返回不同的输出。

公平地说,Mock 确实提供了一种在输入 不同时返回不同输出的方法。然而,这种情况并非如此。输入相同,唯一不同的是调用次数。

问题

如何使用 Mock 实现我的目标?

最佳答案

您可以使用函数 :meck.seq 创建一个按顺序返回给定值的模拟。这依赖于 Mock 只是 meck 之上的薄层这一事实,它允许创建这样的模拟:

  test_with_mock "returns OK when products list is saved into storage", Storage, [],
[
save: fn _table, data -> {:ok, data} end,
get: [{[:_, :_], :meck.seq([
{:ok, nil}, # first call it returns nil
{:ok, [1]} # second call should return some data
])}]
] do

也就是说,不是传递一个匿名函数作为模拟的实现,而是传递一个元组列表,其中每个元组都有一个“参数规范”(在本例中 [:_, :_],以允许任何两个参数)和一个“返回规范”,:meck.seq 返回一个神奇的值,使模拟每次都返回不同的值。

关于mocking - 根据调用函数的次数返回不同的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64555551/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com