perl - Moose "Can' t 定位对象方法"

标签 perl moose

在运行单元测试时,我被告知

Can't locate object method "encode" via package "MockEncodingMethodROT13"


MockEncodingMethodROT13“包”是一个模拟/ stub 的东西。
具体来说,我明白了:

$ prove Test/BFDEn> $ prove Test/BFDEncoder.pm
Test/BFDEncoder.pm .. 1/2

# Failed test 'UseMockROT13_getData died (Can't locate object method "encode" via package "MockEncodingMethodROT13" at BFDEncoder.pm line 30.)'

# at /export/home/me/code/base/Test/Rizzo.pm line 41.

# (in Test::BFDEncoder->UseMockROT13_getData)

# Looks like you failed 1 test of 2.
Test/BFDEncoder.pm .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/2 subtests
(less 1 skipped subtest: 0 okay)


测试和模拟代码如下所示:
package Test::BFDEncoder;

use Test::More;
use BFDEncoder;
use EncodingMethod;
# use EncodingMethodROT13;

##########
{ package MockEncodingMethodROT13;
  use Moose;

  extends 'EncodingMethod';

  override 'encode' => sub {
      my ($self, $data) = @_;

      $data =~ tr/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM/;

      return $data;
  };
}
##########

sub setup : Tests(setup) {
}

sub UseMockROT13_getData : Test(2) {

    my $plaintext = BF->new( data => 'Hello World' );
    my $rot13 = MockEncodingMethodROT13->new;
    my $testee = BFDEncoder->new( decoratedData => $plaintext, encoder => $rot13 );

    is ($testee->getData(), 'Uryyb Jbeyq', caller());
    is ($plaintext->getData(), 'Hello World', caller());
}
原始的 EncodingMethod(和 EncodingMethodROT13)模块如下所示:
package EncodingMethod;
use Moose;
use Carp;

sub encode {
    my ($self, $data) = @_;

    carp(qq["encode" really should be implemented by a subclass.]);

    return $data;
}

1;
package EncodingMethodROT13;
use Moose;

extends 'EncodingMethod';

override 'encode' => sub {
    my ($self, $data) = @_;

    $data =~ tr/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM/;

    return $data;
};
值得注意的是,使用原始(即非模拟)EncodingMethodROT13 的单元测试工作正常,尽管两者的代码实际上是相同的!
我知道它“只是”一个单元测试,当我可以轻松使用原始代码时使用伪造的代码,但我真的很想了解它为什么不起作用。任何想法,任何人?

最佳答案

我相信测试框架在运行前运行测试(也许在 CHECK 时间?)。
但是 override声明,更重要的是 extends语句,发生在运行时。
尝试将包定义包装在 BEGIN 的顶部。堵塞。

BEGIN {
  package MockEncodingMethodROT13;
  use Moose;

  extends 'EncodingMethod';

  override 'encode' => sub {
      my ($self, $data) = @_;

      $data =~ tr/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM/;

      return $data;
  };
}

关于perl - Moose "Can' t 定位对象方法",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39486889/

相关文章:

perl - 为什么 version->parse 在没有预先打印的情况下无法工作?

perl - 修改子程序参数(Perl)

子函数的 Perl 哈希

perl - 驼鹿胁迫和 build 者

perl - 在 Moose 中,如果一个角色定义了一个具有默认值的属性,我如何在我的消费类中更改该默认值?

perl - open3 命令的语法

perl - 如何在我的 perl 脚本中使用特定版本(或更高版本)的 perl 模块?

perl - 如何设置 AoArrayrefs 属性并从标量强制转换为 arrayref?

perl - 如何为 Moose 类型特征实现新句柄?

perl - 如果Moose构建器方法失败,该怎么办?