gpt4 book ai didi

unit-testing - 如何在对模块进行单元测试时模拟导入的子例程

转载 作者:行者123 更新时间:2023-12-02 08:15:12 25 4
gpt4 key购买 nike

考虑一个模块,该模块导出一个连接到 Internet 并返回结果的子程序:

unit module A;

sub download is export {
"result from internet" # Not the actual implementation, obviously.
}

还有另一个导入并调用该子例程的模块:

use A;  # imports &download into this lexical scope
unit module B;

sub do-something is export {
download().uc ~ "!!" # Does something which involves calling &download
}

现在我想为模块 B 编写单元测试。
但我不希望测试实际连接到 Internet;我希望他们使用由我的测试脚本控制的子例程 download 的模拟版本:

use Test;
plan 2;

use B;

my $mock-result;
my &mock-download = -> { $mock-result }

# ...Here goes magic code that installs &mock-download
# as &download in B's lexical scope...

$mock-result = "fake result";
is do-something(), "FAKE RESULT!!", "do-something works - 1";

$mock-result = "foobar";
is do-something(), "FOOBAR!!", "do-something works - 2";

问题是缺少覆盖子 download 的魔术代码...

在 Perl 5 中,我认为这可以使用 glob 赋值很容易地实现,或者在 Sub::Override 的帮助下甚至更好。或 Test::MockModule .

但是在 Perl 6 中,模块 B 的词法作用域在编译完成后关闭,因此在测试脚本运行时不能再被修改(如果我是,请纠正我错误的)。所以这种方法似乎不太可能。

那么,在 Perl 6 中如何解决这个任务呢?
IE。如何为 B::do-something 编写单元测试,而不让它调用真正的 A::download

最佳答案

最简单的方法可能是使用 wrap,这在 https://docs.perl6.org/language/functions#Routines 中有所描述。但前提条件是防止内联的 use soft; pragma。您需要在模块 A 中使用 soft;:

unit module A;
use soft;

sub download is export {
"result from internet";
}

模块 B:

unit module B;
use A;

sub do-something is export {
download.uc ~ "!!";
}

和测试脚本:

use Test;
use A;
use B;

&download.wrap({
"mock result";
});

is do-something, "MOCK RESULT!!", "mock a 'use'd sub";
# ok 1 - mock a 'use'd sub

关于unit-testing - 如何在对模块进行单元测试时模拟导入的子例程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42645801/

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