繁体   English   中英

如何模拟一个完整的模块?

[英]How to mock a full module?

我有一个要测试的模块B 该模块依赖于我不想测试的模块A 这是我的 package B的示例:

use strict;
use warnings FATAL => 'all';

use A;

package B;
    
sub to_test {
    return A::a();
}

在我的单元测试中,我想调用B::to_test但我想手动指定A::a()必须返回的值。 为此,我编写了一个模块MockA.pm ,其中包含要模拟的A的所有子项:

use strict;
use warnings 'FATAL' => 'all';

package Mock::A;

sub a {
    return "From mock";
}
    
1;

我知道我可以使用Test::MockModule轻松模拟A::a ,问题是 package A可能包含很多 subs 并且Test::MockModule让我只能一个一个地模拟它们。

如何使用 MockA 模拟完整A MockA

现有的答案显示了如何替换模块的一部分,这是非常明智的。

但是,如果您想完全替换模块(甚至不需要安装原始模块),您可以使用以下内容:

# 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; 必须出现在use A; .

可以通过 MockA 中的 subs 重新定义MockA A中定义的 subs。 要做到这一点,需要满足三个条件:

  • MockA必须定义与A相同的 package ;
  • A所有包含之后必须包含MockA
  • 警告redefine不能是致命的。

文件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;

并且,在单元测试中:

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM