Chr*_*oms 6 testing tdd perl attributes moose
我目前使用一个块eval来测试我将属性设置为只读.有更简单的方法吗?
工作代码示例:
#Test that sample_for is ready only
eval { $snp_obj->sample_for('t/sample_manifest2.txt');};
like($@, qr/read-only/xms, "'sample_for' is read-only");
Run Code Online (Sandbox Code Playgroud)
更新
感谢Friedo,Ether和Robert P的回答以及Ether,Robert P和jrockway的评论.
我喜欢以太的答案如何$is_read_only通过用它来否定它来确保它只是一个真值或假值(即从不是一个coderef)!.双重否定也提供了这一点.因此,您可以$is_read_only在is()函数中使用,而无需打印出coderef.
有关最完整的答案,请参阅下面的Robert P的答案.每个人都非常乐于助人,并建立在彼此的答案和评论之上.总的来说,我认为他对我的帮助最大,因此他现在已成为公认的答案.再次感谢Ether,Robert P,Friedo和jrockway.
如果您可能想知道,正如我最初所做的那样,这里是关于get_attribute和find_attribute_by_name(来自Class :: MOP :: Class)之间区别的文档:
$metaclass->get_attribute($attribute_name)
This will return a Class::MOP::Attribute for the specified $attribute_name. If the
class does not have the specified attribute, it returns undef.
NOTE that get_attribute does not search superclasses, for that you need to use
find_attribute_by_name.
Run Code Online (Sandbox Code Playgroud)
如Class :: MOP :: Attribute中所述:
my $attr = $this->meta->find_attribute_by_name($attr_name);
my $is_read_only = ! $attr->get_write_method();
Run Code Online (Sandbox Code Playgroud)
$attr->get_write_method() 将获得writer方法(您创建的方法或生成的方法),如果没有,则为undef.
从技术上讲,属性不需要具有读取或写入方法. 大部分时间它会,但并非总是如此.一个例子(从jrockway的评论中慷慨地被盗)如下:
has foo => (
isa => 'ArrayRef',
traits => ['Array'],
handles => { add_foo => 'push', get_foo => 'pop' }
)
Run Code Online (Sandbox Code Playgroud)
此属性将存在,但没有标准的读者和编写者.
因此,要在每种情况下测试属性已被定义为is => 'RO',您需要同时检查write和read方法.你可以用这个子程序做到这一点:
# returns the read method if it exists, or undef otherwise.
sub attribute_is_read_only {
my ($obj, $attribute_name) = @_;
my $attribute = $obj->meta->get_attribute($attribute_name);
return unless defined $attribute;
return (! $attribute->get_write_method() && $attribute->get_read_method());
}
Run Code Online (Sandbox Code Playgroud)
或者,您可以在最后一个之前添加双重否定return来boolify返回值:
return !! (! $attribute->get_write_method() && $attribute->get_read_method());
Run Code Online (Sandbox Code Playgroud)