评估子例程

时间:2016-12-15 15:58:12

标签: perl unit-testing subroutine

关于潜艇回报价值,我有些不太清楚。 我喜欢逐个子地测试我的模块,并检查它们是否发出正确的返回值或者是否出现正确的异常。

例如,假设我有以下代码(X :: Argument :: BadFormat是从Exception :: Class派生的异常处理程序):

    package My::Module;

    use strict;
    use warnings;

    sub new{#does things unrelated to the current question}

    sub my_sub {
        my ($self,$possible_value) = @_;

        if ($possible_value =~ q{\w}) { #Affect value to current object
            $self->{field} = $possible_value;
        }else{ #throw an exception
            X::Argument::BadFormat->throw(
                arg             => 'possible_value',
                expected_format => 'something that looks like a word',
                received_value  => $possible_value,
            );
        }
    }

在测试文件中,我将运行以下测试:

my $object = My::Module->new();
throws_ok(sub {$object->my_sub('*')}, 'X::Argument::BadFormat', 'Faulty value will raise an exception');
ok($object->my_sub('turlututu'));

在以下情况下测试很容易:

  • sub返回一个值
  • 测试条件必须引发异常,

但是,当我只在当前对象中设置字段的值时,我没有理由返回任何内容。

在那种情况下:

  • 是否足以简单地执行代码以将子输出评估为“true”?
  • 我应该添加一个明确的“return 1”; ?
  • sub实际上是否返回了最后一次评估,在这种情况下是
  • 的成功
  • 在“if”中测试?我还没有想到的其他东西,但是 对每个人都很明显吗?

3 个答案:

答案 0 :(得分:3)

在这种情况下,我只需检查以确保正确设置了对象的属性。这就是所有这个特殊的潜艇。如果设置正常,则子设备正确结束。如果没有设置,则在子结束之前出现问题。

my $p='blah'; 
$obj->my_sub($p); 

is $obj->{field}, $p, "my_sub() set the field attr ok";

如果field属性有吸气剂会更好,所以你不打破封装,但我离题了。

答案 1 :(得分:1)

不需要返回值的子句应以

结尾
return;

在你的情况下,没有它,你将返回$ possible_value的值,这是最后执行的事情。返回看起来并不是一件有用的事情。

假设您添加显式返回:

您的throws_ok测试看起来不错。然后,您应该测试该字段是否已正确设置。您的ok测试不是必需的,因为您的子项不会返回任何内容。

答案 2 :(得分:1)

Perl默认返回上次执行代码的结果。

例如:

none

print main(); sub main { my $var = 9 * 7; } 将输出63.如果您的代码可能受到给定子例程输出的影响,那么您需要设置一个返回值(通常认为它最好总是在最后设置一个显式返回值子程序/方法)。

print

print main(); sub main { my $var = 9 * 7; return; } 不会输出任何内容。

就个人而言,我总是尝试根据子例程返回的上下文设置返回值,但是如果你正在编写其他人将要使用的代码,那么通常最安全的做{{1} }。

Perl :: Critic(link to the specific policy)的另一个解释:

  

子程序“main”不会以“sub main {”附近的第8行“return”结束。

     

子程序:: RequireFinalReturn(严重性:4)

     

要求所有子程序使用其中一个明确终止       以下:print鲤鱼',return;死',return',退出',croak',投掷'。

     

在其末尾没有显式返回语句的子例程可以       混乱。推断出返回值将会是多么具有挑战性       是

     

此外,如果程序员并不意味着有一个       一些重要的返回值,并省略了一个返回语句       子程序的内部数据可以泄漏到外面。考虑这种情况:

exec',
     

在这种情况下,check_password()中的最后一个语句是赋值。       该赋值的结果是隐式返回值,所以是错误的       guess返回正确的密码!添加`return;'在那结束       子程序解决了这个问题。

     

唯一允许的例外是空子程序。

     

在解决本政策确定的问题时要小心;不要盲目       把'回归'每个子程序结束时的陈述。