【问题标题】:Unit testing in perl, Receiving hash ref as return expected to return a string from a key in a hashperl 中的单元测试,接收哈希 ref 作为返回期望从哈希中的键返回字符串
【发布时间】:2016-07-24 04:50:14
【问题描述】:

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

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 中的错误哈希:

 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 中的散列的其他键

package ASC::Builder::Error;

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

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

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

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

#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');

最后是我的测试结果:

#   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 

【问题讨论】:

  • 您可能希望正确缩进您的代码。有点难读。

标签: perl unit-testing hash return-type hash-of-hashes


【解决方案1】:

在我的机器上

首先,如果我运行您的代码,我会收到关于 CABLING_CHECK_TOR_INCORRECT_CABLING_ERROR 未定义的错误。如果我将其替换为 CABLING_ERROR,则测试将因此失败。

#          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() 不做数据结构。您可以使用Test::Deep 来执行此操作。

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 进行比较。

测试清晰

但是,这可能无法解决您的实际问题。不要让一个测试用例检查两种可能的事情,而是为每个可能的输入创建一个专用测试用例。这就是单元测试的意义所在。

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';

上面的代码会给你两个测试用例。一个用于 direct 错误字符串,另一个用于 indirect 散列。

ok 1 - direct error message gets read correctly
ok 2 - indirect error message gets read correctly
1..2

不要浪费时间

同时,这也解决了您方法的另一个问题。在单元测试中,您希望测试尽可能小的单元。不要将它们与您的其他业务逻辑或业务生产数据联系起来。

您的ASC::Builder::Error 类不关心错误的类型,因此不要通过加载附加内容来为您提供与现实生活中完全相同的错误消息而过于复杂。只需使用足以证明东西有效的简单事物。

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

【讨论】:

  • 抱歉第一个语法错误,我从错误的版本中复制了代码。我现在将通过您的回答和建议。谢谢。
  • Perl Test::Deep 库不可用,我没有添加它的权限。我认为有一种非常尴尬的深入比较方式。可用的只有Test::More。感谢上面的建议,我将它们分成两个单独的测试用例,毕竟它们是单元测试更有意义。哈哈
  • @Paul 拆分它是我认为的最佳选择。
  • 所以两个单独的测试,一个用于$error_string,一个用于$error_hash ?
  • @paul 您可以将其发布到 codereview 堆栈交换并使用 Perl 标记它,并提供更多关于它的作用的信息。然后,我们可以为您提供有关您的代码的主题反馈。还有一些问题我想解决,但这不是真正的地方。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-21
  • 2021-11-19
  • 1970-01-01
  • 2020-04-05
  • 2011-05-19
  • 2021-10-01
  • 1970-01-01
相关资源
最近更新 更多