首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在perl中进行单元测试,接收哈希引用作为返回,期望从散列中的键返回字符串。

在perl中进行单元测试,接收哈希引用作为返回,期望从散列中的键返回字符串。
EN

Stack Overflow用户
提问于 2016-04-04 14:58:57
回答 1查看 365关注 0票数 0

我正在尝试测试以下方法的输出:

代码语言:javascript
运行
复制
package ASC::Builder::Error;

sub new {

    my ($package, $first_param) = (shift, shift);


    if (ref $first_param eq 'HASH') {
        my %params = @_;
        return bless { message => $first_param->{message}, %params}, $package;
    }
    else {
        my %params = @_; 
        return bless {message => $first_param, %params}, $package;

}   
}

此方法应该接受错误散列或错误字符串。如果它接受一个哈希,它应该从错误哈希输出消息键的值。

这是位于ErrorLibrary.pm中的错误哈希:

代码语言:javascript
运行
复制
 use constant {

        CABLING_ERROR => {
        code => 561,
        message => "cabling is not correct at T1",
        tt => { template => 'disabled'},
        fatal => 1,
        link =>'http://www.e-solution.com/CABLING_ERROR',
        },
    };

这是消息方法以及位于Error.pm中的散列的其他键。

代码语言:javascript
运行
复制
package ASC::Builder::Error;

sub message {
        return $_[0]->{message}; 
}

sub tt {
    return {$_[0]->{tt} };
}

sub code {
    return {$_[0]->{code} };
}

这是位于error.t中的当前单元测试。

代码语言:javascript
运行
复制
#input value will either be a String or and Error Message Hash


# error hash
my $error_hash = CABLING_ERROR;
# error string
my $error_string = "cabling is not correct at T1.";

# error hash is passed into new and an error object is outputted
my $error_in = ASC::Builder::Error->new($error_hash);

# checks to see if the output object from new is an Error object
isa_ok($error_in, 'ASC::Builder::Error');

# checking that object can call the message() method
can_ok( $error_in, 'message');


# checks to see if the output message matches the message contained in the error hash(correct)
is($error_in->message(),( $error_string || $error_hash->{message} ), 'Returns correct error message');

最后,我的测试结果:

代码语言:javascript
运行
复制
#   Failed test 'Returns correct error message'
#   at t/67_error_post.t line 104.
#          got: 'HASH(0x38b393d490)'
#     expected: 'cabling is not correct at T1.'
# 
# '
# Looks like you failed 1 test of 3.
t/67_error_post.t .. Dubious, test returned 1 (wstat 256, 0x100)
Failed 1/3 subtests 
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2016-04-04 15:23:12

在我的机器上

首先,如果我运行您的代码,就会得到一个关于CABLING_CHECK_TOR_INCORRECT_CABLING_ERROR未定义的错误。如果我用CABLING_ERROR替换它,那么测试就会失败。

代码语言:javascript
运行
复制
#          got: 'cabling is not correct at T1'
#     expected: 'cabling is not correct at T1.'
# Looks like you failed 1 test of 3.

同时有两个可能的产出

现在开始你所说的输出。

由于某些原因,您的$error_in->message返回一个hashref,它会被is()压缩,因为is()不执行数据结构。您可以使用试验:深度来完成此操作。

代码语言:javascript
运行
复制
use Test::Deep;

cmp_deeply(
    $error_in->message,
    any(
        $error_string,
        $error_hash->{message},
    ),
    'Returns correct error message',
);

在这里,我假设您的$error_string || $error_hash->{message}是为了让它检查其中一个或另一个。

但是||只会检查$error_string是否有真值并返回它,或者取$error_hash->{message}的值。它将该操作的结果与$error_in->message进行了比较。

测试清楚

然而,这可能不会解决你真正的问题。与其让一个测试用例检查两个可能的事情,不如为每个可能的输入创建一个专用的测试用例。这就是单元测试的意义所在。

代码语言:javascript
运行
复制
my $error_direct = ASC::Builder::Error->new('foo');
is $error_direct->message, 'foo', 'direct error message gets read correctly';

my $error_indirect = ASC::Builder::Error->new( { message => 'bar' } );
is $error_indirect->message, 'bar', 'indirect error message gets read correctly';

以上代码将为您提供两个测试用例。一个用于直接错误字符串,另一个用于间接散列。

代码语言:javascript
运行
复制
ok 1 - direct error message gets read correctly
ok 2 - indirect error message gets read correctly
1..2

不要浪费时间

同时,这也解决了您的方法的另一个问题。在单元测试中,您希望测试最小的单元。不要将它们绑定到其他业务逻辑或业务生产数据。

您的ASC::Builder::Error类并不关心错误的类型,所以不要通过加载一些附加的东西来提供与实际生活中完全相同的错误消息,从而使错误变得过于复杂。只要使用简单的东西,就足以证明这些东西是有效的。

单元测试越简单,维护它们就越容易,并且一旦有了更多的案例,就越容易添加。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/36406158

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档