驼鹿“找不到对象方法”

时间:2016-09-14 09:25:06

标签: perl moose

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

  

无法通过包“MockEncodingMethodROT13”找到对象方法“encode”

MockEncodingMethodROT13“包”是模拟/存根的东西。

具体来说,我明白了:

  

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

     

#Failed测试'UseMockROT13_getData死了(无法通过BFDEncoder.pm第30行的软件包“MockEncodingMethodROT13”找到对象方法“编码​​”。)'

     

#at /export/home/me/code/base/Test/Rizzo.pm第41行。

     

#(在Test :: BFDEncoder-> UseMockROT13_getData中)

     

#看起来你的2次测试失败了。
  测试/ BFDEncoder.pm ..可疑,测试返回1(wstat 256,0x100)
  1/2子测试失败        (少了1个跳过子测试:0好的)

测试和模拟代码如下所示:

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的单元测试工作正常,尽管两者的代码实际上完全相同!

我知道它是“仅”一个单元测试,当我可以轻松使用原始代码时使用伪造代码,但我真的很想理解为什么它不起作用。任何想法,任何人?

1 个答案:

答案 0 :(得分:0)

我相信测试框架会在运行时之前运行测试(也许在检查时间?)。

但是override语句,更重要的是extends语句在运行时发生。

尝试将软件包定义包装在BEGIN块的顶部。

BEGIN {
  package MockEncodingMethodROT13;
  use Moose;

  extends 'EncodingMethod';

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

      $data =~ tr/abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/nopqrstuvwxyzabcdefghijklmNOPQRSTUVWXYZABCDEFGHIJKLM/;

      return $data;
  };
}