通用跟踪模拟 class
Generic tracing mock class
我正在尝试使用 moops 构建一个方便的模拟 class:
#!/usr/bin/env perl
use Modern::Perl '2014';
use Moops;
use Test::More;
class aClass {
method m {}
method l {}
};
class NotWorkingMockAClass
extends aClass {
has methodCallLog => (
is => 'rw',
default => sub { [] },
isa => ArrayRef
);
around m, l {
push $self->methodCallLog, (caller(0))[3] =~ m/::(\w+)$/;
$next->($self, @_ );
}
};
my $mac = NotWorkingMockAClass->new();
$mac->m();
$mac->l();
$mac->m();
is( ($mac->methodCallLog)->[0], 'm', 'mcl[0] == m' );
is( ($mac->methodCallLog)->[1], 'l', 'mcl[1] == l' );
is( ($mac->methodCallLog)->[2], 'm', 'mcl[2] == m' );
这产生:
$ perl mocking.pl
ok 1 - mcl[0] == m
not ok 2 - mcl[1] == l
# Failed test 'mcl[1] == l'
# at mocking.pl line 33.
# got: 'm'
# expected: 'l'
ok 3 - mcl[2] == m
所以,问题似乎是,当我使用 around m,l ..
快捷方式时,caller()
总是 returns m
。
像这样定义 class:
class WorkingMockAClass
extends aClass {
has methodCallLog => (
is => 'rw',
default => sub { [] },
isa => ArrayRef
);
method _logAndDispatch( CodeRef $next, ArrayRef $args ){
push $self->methodCallLog, (caller(1))[3] =~ m/::(\w)$/;
$next->($self, @$args );
}
around m {
$self->_logAndDispatch( $next, \@_ );
}
around l {
$self->_logAndDispatch( $next, \@_ );
}
};
有效,但写起来有点冗长和麻烦。
是否有更好的选择来使用 Moops 实现类似的目标?
无论是 Moops 还是其他方面,我都不会相信 caller
任何可能会对其应用修饰符的方法。我也不会信任那些修饰符。您过分依赖方法修饰符工作原理的内部结构。 (这将在 Moo/Moose/Mouse 之间有所不同。)
你试过这样的东西吗?
push @{ $self->methodCallLog }, Sub::Identify::sub_name($next);
(或使用 Sub::Util 而不是 Sub::Identify。)
我正在尝试使用 moops 构建一个方便的模拟 class:
#!/usr/bin/env perl
use Modern::Perl '2014';
use Moops;
use Test::More;
class aClass {
method m {}
method l {}
};
class NotWorkingMockAClass
extends aClass {
has methodCallLog => (
is => 'rw',
default => sub { [] },
isa => ArrayRef
);
around m, l {
push $self->methodCallLog, (caller(0))[3] =~ m/::(\w+)$/;
$next->($self, @_ );
}
};
my $mac = NotWorkingMockAClass->new();
$mac->m();
$mac->l();
$mac->m();
is( ($mac->methodCallLog)->[0], 'm', 'mcl[0] == m' );
is( ($mac->methodCallLog)->[1], 'l', 'mcl[1] == l' );
is( ($mac->methodCallLog)->[2], 'm', 'mcl[2] == m' );
这产生:
$ perl mocking.pl
ok 1 - mcl[0] == m
not ok 2 - mcl[1] == l
# Failed test 'mcl[1] == l'
# at mocking.pl line 33.
# got: 'm'
# expected: 'l'
ok 3 - mcl[2] == m
所以,问题似乎是,当我使用 around m,l ..
快捷方式时,caller()
总是 returns m
。
像这样定义 class:
class WorkingMockAClass
extends aClass {
has methodCallLog => (
is => 'rw',
default => sub { [] },
isa => ArrayRef
);
method _logAndDispatch( CodeRef $next, ArrayRef $args ){
push $self->methodCallLog, (caller(1))[3] =~ m/::(\w)$/;
$next->($self, @$args );
}
around m {
$self->_logAndDispatch( $next, \@_ );
}
around l {
$self->_logAndDispatch( $next, \@_ );
}
};
有效,但写起来有点冗长和麻烦。
是否有更好的选择来使用 Moops 实现类似的目标?
无论是 Moops 还是其他方面,我都不会相信 caller
任何可能会对其应用修饰符的方法。我也不会信任那些修饰符。您过分依赖方法修饰符工作原理的内部结构。 (这将在 Moo/Moose/Mouse 之间有所不同。)
你试过这样的东西吗?
push @{ $self->methodCallLog }, Sub::Identify::sub_name($next);
(或使用 Sub::Util 而不是 Sub::Identify。)