[英]How to mock a full module?
I have a module B
that I want to test.我有一个要测试的模块
B
This module depends on the module A
that I don't want to test.该模块依赖于我不想测试的模块
A
Here is an example of my package B
:这是我的 package
B
的示例:
use strict;
use warnings FATAL => 'all';
use A;
package B;
sub to_test {
return A::a();
}
In my unit test, I would like to call B::to_test
but I want to manually specify what value A::a()
must return.在我的单元测试中,我想调用
B::to_test
但我想手动指定A::a()
必须返回的值。 To do that, I have written a module MockA.pm
that contains all the subs of A
to mock:为此,我编写了一个模块
MockA.pm
,其中包含要模拟的A
的所有子项:
use strict;
use warnings 'FATAL' => 'all';
package Mock::A;
sub a {
return "From mock";
}
1;
I know I can easily mock A::a
using Test::MockModule
, the problem is the package A
may contain a lot of subs and Test::MockModule
lets me mock them only one by one.我知道我可以使用
Test::MockModule
轻松模拟A::a
,问题是 package A
可能包含很多 subs 并且Test::MockModule
让我只能一个一个地模拟它们。
How can I mock the full A
package with MockA
?如何使用 MockA 模拟完整
A
MockA
?
The existing answer shows how to replace parts of a module, which is quite sensible.现有的答案显示了如何替换模块的一部分,这是非常明智的。
But if you wanted to replace the module entirely (to the point that the original doesn't even need to be installed), you can use the following:但是,如果您想完全替换模块(甚至不需要安装原始模块),您可以使用以下内容:
# Use the name of the package we're mocking.
package A;
...
# Tell Perl that the module we're mocking has been loaded.
$INC{ ( __PACKAGE__ =~ s{::}{/}rg ) . '.pm' } = 1;
use MockA;
must appear before any instances of use A;
必须出现在
use A;
. .
It is possible to redefine the subs defined in the package A
by the subs in MockA
.可以通过 MockA 中的 subs 重新定义
MockA
A
中定义的 subs。 To do that, there are three conditions:要做到这一点,需要满足三个条件:
MockA
must define the same package than A
; MockA
必须定义与A
相同的 package ;MockA
must be included after all the inclusions of A
;A
所有包含之后必须包含MockA
;redefine
must not be fatal.redefine
不能是致命的。 The file MockA.pm
can be the following:文件
MockA.pm
可以是以下内容:
use strict;
# No fatal error if a sub is redefined
use warnings 'FATAL' => 'all', 'NONFATAL' => 'redefine';
# Override package A
package A;
sub a {
return "From mock";
}
1;
And, in the unit test:并且,在单元测试中:
use B; # B includes A
use MockA; # MockA overrides A
B::to_test() # B calls MockA::a
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.