Catalyst 中的 Moose 访问器("Can't use string as HASH ref" 错误)
Moose accessors in Catalyst ("Can't use string as HASH ref" error)
非常简单的问题:
package MyApp::Model::Foo;
use Moose;
use namespace::autoclean;
extends 'Catalyst::Model';
has 'firstname' => ( is => 'ro', isa => 'Str' ); # to be populated in config file
# ...
sub check_name {
my $self = shift;
my $firstname = $self->firstname;
# ...
}
当我从测试脚本调用 check_name()
时,在“$self->firstname”行出现错误 Can't use string ("MyApp::Model::Foo") as a HASH ref while "strict refs" in use at reader MyApp::Model::Foo::firstname
。我该如何使用它?
我无法重现测试内容,因为它太广泛了,但是当我 运行 测试脚本时,我已经调用了一个安装脚本来加载 Catalyst 应用程序(因此读取 Catalyst配置文件),部署和填充数据库表等
测试脚本在原始版本中运行良好(它没有从配置文件中获取值;这就是我现在正在尝试做的;最初我传入了一个值),相关位很简单
my $name_check = MyApp::Model::Foo->check_name();
ok(defined $name_check, "Name is OK");
您似乎想要进行某种单元测试,或者可能是集成测试,并验证您的应用程序是否从配置文件中获取了正确的数据。
Catalyst 组件(模型、视图和控制器)是 Moose 对象,您没看错。为了让它们拥有 Moose 魔法(这并不是真正的魔法),您需要实例化它们。您不能只将访问器作为 class 方法来调用。
use MyApp::Model::Foo;
my $name_check = MyApp::Model::Foo->new->check_name();
但那是行不通的,因为现在您已经有了模型对象的 new 实例,并且它没有通过配置设置名称。
Catalyst 在内部负责为您创建对象,包括它们的配置。你说你有催化剂 运行。您可以使用 Catalyst::Test 进入那里,获取上下文对象 $c
然后使用 model
访问器为您获取正确类型的模型对象,该对象已被赋予配置。
ctx_request
函数让 Catalyst 处理请求和 returns 实际的 HTTP::Response 对象以及上下文对象。然后您可以使用该上下文。
use Catalyst::Test 'MyApp';
use Test::More;
my ( $res, $c ) = ctx_request('/');
ok defined $c->model('Foo')->name, 'Name is defined';
您的测试堆栈中的某处可能已经有 Catalyst::Test。如果不是,那你就是在做一些奇怪的事情。
请注意,如果您想要附加到某个用户的会话,这将不起作用,因此如果您有一个 Test::WWW::Mechanize::Catalyst or another user agent that has a session cookie, you will need to extract the cookie and build your own HTTP::Request 对象,请使用用户代理 cookie jar 将 cookie 放入该请求在将其传递给 ctx_request
.
之前
另请注意,您正在进行的测试不是很有用,除非您正在构建执行配置读取的代码。即便如此,您也可以构建不需要完整 运行 Catalyst 的单元测试。
非常简单的问题:
package MyApp::Model::Foo;
use Moose;
use namespace::autoclean;
extends 'Catalyst::Model';
has 'firstname' => ( is => 'ro', isa => 'Str' ); # to be populated in config file
# ...
sub check_name {
my $self = shift;
my $firstname = $self->firstname;
# ...
}
当我从测试脚本调用 check_name()
时,在“$self->firstname”行出现错误 Can't use string ("MyApp::Model::Foo") as a HASH ref while "strict refs" in use at reader MyApp::Model::Foo::firstname
。我该如何使用它?
我无法重现测试内容,因为它太广泛了,但是当我 运行 测试脚本时,我已经调用了一个安装脚本来加载 Catalyst 应用程序(因此读取 Catalyst配置文件),部署和填充数据库表等
测试脚本在原始版本中运行良好(它没有从配置文件中获取值;这就是我现在正在尝试做的;最初我传入了一个值),相关位很简单
my $name_check = MyApp::Model::Foo->check_name();
ok(defined $name_check, "Name is OK");
您似乎想要进行某种单元测试,或者可能是集成测试,并验证您的应用程序是否从配置文件中获取了正确的数据。
Catalyst 组件(模型、视图和控制器)是 Moose 对象,您没看错。为了让它们拥有 Moose 魔法(这并不是真正的魔法),您需要实例化它们。您不能只将访问器作为 class 方法来调用。
use MyApp::Model::Foo;
my $name_check = MyApp::Model::Foo->new->check_name();
但那是行不通的,因为现在您已经有了模型对象的 new 实例,并且它没有通过配置设置名称。
Catalyst 在内部负责为您创建对象,包括它们的配置。你说你有催化剂 运行。您可以使用 Catalyst::Test 进入那里,获取上下文对象 $c
然后使用 model
访问器为您获取正确类型的模型对象,该对象已被赋予配置。
ctx_request
函数让 Catalyst 处理请求和 returns 实际的 HTTP::Response 对象以及上下文对象。然后您可以使用该上下文。
use Catalyst::Test 'MyApp';
use Test::More;
my ( $res, $c ) = ctx_request('/');
ok defined $c->model('Foo')->name, 'Name is defined';
您的测试堆栈中的某处可能已经有 Catalyst::Test。如果不是,那你就是在做一些奇怪的事情。
请注意,如果您想要附加到某个用户的会话,这将不起作用,因此如果您有一个 Test::WWW::Mechanize::Catalyst or another user agent that has a session cookie, you will need to extract the cookie and build your own HTTP::Request 对象,请使用用户代理 cookie jar 将 cookie 放入该请求在将其传递给 ctx_request
.
另请注意,您正在进行的测试不是很有用,除非您正在构建执行配置读取的代码。即便如此,您也可以构建不需要完整 运行 Catalyst 的单元测试。