如何测试::更多、更智能的交易?

问题描述 投票:0回答:1

目前我正在创建这样的事务测试:

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 块和子测试的末尾,而不是错误实际发生的位置。而且很快就会有很多无聊的样板代码。

如何以更聪明的方式做到这一点?

perl testing transactions try-catch
1个回答
2
投票

事实上,错误 (

croak
) 是在
try-catch-finally
的末尾报告的,而不是在调用有问题的代码的地方,这似乎是由于
Try::Tiny
与命名空间的混淆所致;请参阅这篇文章中的讨论和评论。在复杂的 try 子中,我不清楚这种不当行为的确切来源。一个简单的演示

use warnings;
use strict;
use feature 'say';

use Carp qw(croak);
use Try::Tiny;

sub this_croaks { croak "ouch from a sub in ", __PACKAGE__ }  # line 8

try {
    this_croaks();                    # line 11
}
catch   { print "In try: $_" }
finally { say "clean up" };           # line 14

此打印

在尝试中:来自 try_tiny_mixup.pl 第 14 行 main 中的子程序。
清理

但是

croak
-ing 子函数是在第 11 行调用的,因此应该报告它,而不是第 14 行。

croak
更改为
die
会打印
line 8
(这当然不是解决方案),同时使用
eval
而不是
Try::Tiny
会打印出正确的
line 11
(什么是有效的解决方案) 。请参阅链接的帖子。我不知道
Try::Tiny
是否有修复,但有直接替代品,请参见下文。

我不认为这以任何方式取决于执行的测试(正如我们所知,这里涉及数据库事务)。如果没有可运行的示例,我无法更具体地检查。

最有效的一件事是恢复到

eval
,从 5.14 开始,它不再带有 Try::Tiny 所声明原因的微妙之处。喜欢
eval {
    this_croaks();
};
if ($@) { 
    print "In eval: $@";
}
say "clean up";

这仍然是过时的,但它的工作原理正如预期的那样(并且
Try::Tiny

带有自己的

扭曲
)。 希望即将推出的原生

try/catch

(在 5.34.0 中作为 实验性引入)不会出现这样的问题。§ 目前还没有 use warnings; use v5.34.0; use Carp qw(croak); use experimental 'try'; sub this_croaks { croak "ouch from a sub in ", __PACKAGE__ } # line 9 try { this_croaks(); # line 12 } catch ($e) { print "In try: $e"; } say "clean up"; # there is no "finally" keyword (see text and links) (The pragma [experimental](https://perldoc.perl.org/experimental) replaces the otherwise needed two statements for using experimental features.)

这正确地将其固定在第 12 行(来自第 9 行)。请注意,目前还没有 
finally

关键字。模块

Syntax::Keyword::Tiny
(参见脚注)确实有它,因此可以使用它作为
Try::Tiny
的直接替代品。
我怀疑清除这个问题也会清除测试的行为。 (但我没有测试过。)


匿名子句的语法辅助(“糖”)(在很多方面并不那么幼稚)

提交了错误报告

§

这是作者自己从 Syntax::Keyword::Try 移植的,所以你可能想尝试一下 - 但最好使用 Feature::Compat::Try,他们说。请参阅两者的文档,并查看其跟踪器 一旦我们进行实验,请参阅

perexperiment

© www.soinside.com 2019 - 2024. All rights reserved.