Test :: MockTime在某些情况下不会模拟时间

时间:2015-12-17 09:11:42

标签: linux perl unit-testing testing mocking

我有一个非常简单的脚本,它使用Test :: MockTime来模拟时间,但time调用的输出在代码的两个部分中是不同的。 这是脚本:

package mocker;

use strict;
use warnings;

sub abcd {
    print "in abcd, time is " . time . "\n";
}

BEGIN {
    use Test::MockTime qw(set_absolute_time restore_time);
    set_absolute_time(0);
};

sub do_mock {
    print "Current epoch in do_mock is: " . time . "\n";
    abcd;
    restore_time();
}

1;

我在我的脚本中调用mocker::do_mock

use strict;
use warnings;

use mocker;

mocker::do_mock;

我希望输出在两个打印语句中都是“0”作为当前时间,但奇怪的是我有这个输出:

Current epoch in do_mock is: 0
in abcd, time is 1450343385

那么,为什么abcd时间恢复到当前时间?

2 个答案:

答案 0 :(得分:2)

Test :: MockTime的documentation解释说“它在编译时覆盖了localtimegmtimetime 。”所以:

print "Before: " . time; # Uses CORE::time()

use Test::MockTime;      # Override time()

print "After: " . time;  # Uses overridden time()

您可以使用B::Deparse

查看此内容
$ perl -MO=Deparse foo
print 'Before: ' . time;
use Test::MockTime;
print 'After: ' . &CORE::GLOBAL::time();
foo syntax OK

time()的第二次调用实际上使用了CORE::GLOBAL::time(),这是被覆盖的版本。

要修复,请确保在调用time()之前编译Test :: MockTime:

package mocker;

use strict;
use warnings;

use Test::MockTime qw(set_absolute_time restore_time);

sub abcd {
    print "in abcd, time is " . time . "\n";
}

BEGIN {
    set_absolute_time(0);
};

sub do_mock {
    print "Current epoch in do_mock is: " . time . "\n";
    abcd;
    restore_time();
}

1;

答案 1 :(得分:1)

您可以看到this answer以更好地了解BEGIN块的工作方式。

这里的要点是它在主体之前执行,但它也必须被编译。这意味着您声明声明和BEGIN块的顺序是相关的。