在 Raku 中进行单元测试时如何模拟类方法 [英] How to mock a class method when unittesting in Raku
问题描述
假设我有一个这样的类:
Suppose I have a class like this:
class MyClass {
method data-is-valid {
return self!get-data ~~ m{^From};
}
method !get-data {
return 'From Internet';
}
}
其中 !get-data
方法从 Internet 获取一些数据.
where !get-data
method gets some data from Internet.
是否可以模拟该方法,使其返回我自己的硬编码数据,以便我可以在不连接互联网的情况下测试模块?
Is it possible to mock that method so that it returns my own hardcoded data so I can test the module without connecting to the Internet?
理想情况下,解决方案不应以任何方式修改类的定义.
Ideally, the solution should not modify the definition of the class in any way.
注意:类似问题 存在关于模块的单元测试子程序.
NOTE: A similar question exists regarding unittesting subroutines of modules.
推荐答案
我会首先重构以将获取逻辑拉出到不同的对象,并使 MyClass
依赖于它:
I would first refactor to pull the fetching logic out to a different object, and make MyClass
depend on it:
class Downloader {
method get-data {
return 'From Internet';
}
}
class MyClass {
has Downloader $.downloader .= new;
method data-is-valid {
return $!downloader.get-data ~~ m{^From};
}
}
这是一个依赖倒置的例子,它是一种使代码可测试的有用技术(并且倾向于使其更容易以其他方式演化).
This is an example of dependency inversion, which is a helpful technique for making code testable (and tends to make it easier to evolve in other ways too).
通过此更改,现在可以使用 Test::Mock 模块来模拟下载器
:
With this change, it is now possible to use the Test::Mock module to mock Downloader
:
use Test;
use Test::Mock;
subtest 'Is valid when contains From' => {
my $downloader = mocked Downloader, returning => {
get-data => 'From: blah'
};
my $test = MyClass.new(:$downloader);
ok $test.data-is-valid;
check-mock $downloader,
*.called('get-data', :1times);
}
subtest 'Is not valid when response does not contain From' => {
my $downloader = mocked Downloader, returning => {
get-data => 'To: blah'
};
my $test = MyClass.new(:$downloader);
nok $test.data-is-valid;
check-mock $downloader,
*.called('get-data', :1times);
}
这篇关于在 Raku 中进行单元测试时如何模拟类方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!