如何测试::更多、更智能的交易?
目前我正在创建这样的事务测试:
use Test::More;
use Try::Tiny;
my $dbh = ...;
subtest 'do something envolving a transaction' => sub {
$dbh->begin_work();
try {
my $obj = create_in_db({...}, $dbh);
my $result = MyTestObject->new()->do_something($obj);
ok $result "We've got great results";
} catch {
croak $_;
} finally {
$dbh->rollback(); #kills $obj
};
};
done_testing();
1;
这可行,但有缺点,错误行始终是 catch 块和子测试的末尾,而不是错误实际发生的位置。而且很快就会有很多无聊的样板代码。
如何以更聪明的方式做到这一点?
Currently I am creating transactional tests like that:
use Test::More;
use Try::Tiny;
my $dbh = ...;
subtest 'do something envolving a transaction' => sub {
$dbh->begin_work();
try {
my $obj = create_in_db({...}, $dbh);
my $result = MyTestObject->new()->do_something($obj);
ok $result "We've got great results";
} catch {
croak $_;
} finally {
$dbh->rollback(); #kills $obj
};
};
done_testing();
1;
This works, but has the disadvantage, that the line of the error is always the catch block and the end of the subtest, never where the error actually happens. And it is a lot of boring boilerplate code that quickly adds up.
How to do this in a smarter way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
事实上,错误 (
croak
) 是在try-catch-finally
块† 的末尾报告的,而不是在调用有问题的代码的地方报告的似乎是由于Try::Tiny
与名称空间的混淆所致;请参阅这篇文章中的讨论和评论。在复杂的 尝试子。一个简单的演示打印
But the
croak
-ing sub is called at line 11 so that should be reports, not line 14.‡更改
croak
todie
使其打印line 8
(这当然不是解决方案),同时使用eval
而不是Try::Tiny
结果正确第 11 行
已打印(什么是有效的解决方案)。请参阅链接的帖子。我不知道Try::Tiny
是否有修复,但有直接替代品,请参见下文。我不认为这以任何方式取决于执行的测试(正如我们所知,这里涉及数据库事务)。如果没有可运行的示例,我无法更具体地检查。
完全有效的一件事是恢复到
eval
,自 5.14 起 不再带有Try::Tiny
所声明的原因的微妙之处。 LikeThis 仍然过时,但它的工作原理就像预期的那样(并且
Try::Tiny
带有 自己的扭曲)。希望即将到来的原生try/catch,引入为5.34.0 中的实验,不会出现这样的问题。§目前还没有
(pragma experimental 替换了实验功能所需的两个语句。)
这正确地将其固定为第 12 行(来自第 9 行)的调用。请注意,还没有
finally
关键字。模块Syntax::Keyword::Tiny
(参见脚注)确实有它,因此可以使用它作为Try::Tiny
的直接替代品。我怀疑清除这个问题也会清除测试的行为。 (但我没有测试这一点。)
† 匿名子句的语法辅助(“糖”)(在很多方面并不那么幼稚)
‡ 已提交错误报告
§ 这是从 Syntax::Keyword::Try 由作者自己编写,因此您可能想尝试一下 - 但最好使用 功能::兼容::尝试,他们说。请参阅两者的文档,并查看其跟踪器。
当我们进行实验时,请参阅 perlexperiment。
The fact that the error (
croak
) is reported at the end oftry-catch-finally
blocks† instead of where the offending code is called seems due toTry::Tiny
's mixup with namespaces; see a discussion in this post and comments. The exact source of this misbehavior isn't clear to me in the complex try sub. A simple demoThis prints
But the
croak
-ing sub is called at line 11 so that should be reported, not line 14.‡Changing
croak
todie
makes it printline 8
(what of course isn't a solution) while usingeval
instead ofTry::Tiny
results in the correctline 11
printed (what is a valid solution). See the linked post. I am not aware of a fix withTry::Tiny
but there are drop-in replacements, see below.I don't see that this in any way depends on what tests are performed (here involving a database transaction as we are told). And I cannot check more specifically without a runable example.
The one thing that works fully is to revert to
eval
, which since 5.14 isn't anymore borne with subtleties that were the stated reason forTry::Tiny
. LikeThis is still archaic but it works just as intended (and
Try::Tiny
comes with twists of its own).Hopefully the coming native try/catch, introduced as experimental in 5.34.0, won't have problems like this.§ For now it doesn't
(The pragma experimental replaces the two statements needed for experimental features.)
This correctly pegs it as called at line 12 (and coming from line 9). Note that there is no
finally
keyword yet. The moduleSyntax::Keyword::Tiny
(see footnote) does have it so it may be possible to use it as a drop-in replacement forTry::Tiny
.I suspect that clearing this up will clear up the test's behavior as well. (But I didn't get to test that.)
† Syntax aids ("sugar") for anonymous subs (which in many ways aren't so naive)
‡ Submitted a bug report
§ This is getting ported from Syntax::Keyword::Try by the author themselves so you may want to try that -- but then better use Feature::Compat::Try, they say. See docs of both, and see its tracker.
Once we are at experimental stuff see perlexperiment.