首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >为什么我的Perl单元测试在EPIC中失败而在调试器中工作?

为什么我的Perl单元测试在EPIC中失败而在调试器中工作?
EN

Stack Overflow用户
提问于 2009-11-18 21:22:36
回答 2查看 688关注 0票数 1

是否有人经历过失败的单元测试,当他们试图调试它以找出故障发生的地方时,单元测试在调试器中运行代码时会成功?

我使用Eclipse3.5.1和EPIC 0.6.35以及ActiveState ActivePerl 5.10.0。我用多个例程编写了模块A和模块B。模块B中的一个例程调用A模块中的一组例程,我将把模拟对象添加到我的模块B单元测试文件中,以尝试在B模块上获得更完整的代码覆盖,其中模块B中的代码进行测试,以查看所有对模块作为例程的调用是否失败或成功。因此,我在单元测试中添加了一些模拟对象,以强制一些模块A例程返回故障,但我并没有像预期的那样得到故障。当我调试我的单元测试文件时,对模块A例程的调用确实按预期失败(并且我的单元测试成功了)。当我在没有调试的情况下正常运行单元测试文件时,对模拟模块A例程的调用不会像预期的那样失败(并且我的单元测试失败)。

这里会发生什么事?如果我可以使用一组简单的代码使问题失败,我将尝试发布一个问题的工作示例。

增编:,我的代码被压缩到了一个最基本的集合,这说明了我的问题。问题的详细情况和工作实例如下:

我的Eclipse项目包含一个包含两个模块的"lib“目录..。MainModule.pm和UtilityModule.pm.我的Eclipse项目还在顶层包含一个名为MainModuleTest.t的单元测试文件和一个名为input_file.txt的文本文件,其中只包含一些垃圾文本。

代码语言:javascript
运行
复制
EclipseProject/
    MainModuleTest.t
    input_file.txt
    lib/
        MainModule.pm
        UtilityModule.pm

MainModuleTest.t文件的内容:

代码语言:javascript
运行
复制
use Test::More qw(no_plan);
use Test::MockModule;
use MainModule qw( mainModuleRoutine );

$testName = "force the Utility Module call to fail";
# set up mock utility routine that fails
my $mocked = new Test::MockModule('UtilityModule');
$mocked->mock( 'slurpFile', undef );
# call the routine under test
my $return_value = mainModuleRoutine( 'input_file.txt' );
if ( defined($return_value) ) {
    # failure; actually expected undefined return value
    fail($testName);
}
else {
    # this is what we expect to occur
    pass($testName); 
}

MainModule.pm文件的内容:

代码语言:javascript
运行
复制
package MainModule;

use strict;   
use warnings; 
use Exporter; 
use base qw(Exporter); 
use UtilityModule qw( slurpFile );

our @EXPORT_OK = qw( mainModuleRoutine );

sub mainModuleRoutine {
    my ( $file_name ) = @_;
    my $file_contents = slurpFile($file_name);
    if( !defined($file_contents) ) {
        # failure
        print STDERR "slurpFile() encountered a problem!\n";
        return;
    }
    print "slurpFile() was successful!\n";
    return $file_contents;
}

1;  

UtilityModule.pm文件的内容:

代码语言:javascript
运行
复制
package UtilityModule;

use strict;   
use warnings; 
use Exporter; 
use base qw(Exporter); 

our @EXPORT_OK = qw( slurpFile );

sub slurpFile {
    my ( $file_name ) = @_;
    my $filehandle;
    my $file_contents = "";
    if ( open( $filehandle, '<', $file_name ) ) {
        local $/=undef;
        $file_contents = <$filehandle>;
        local $/='\n';
        close( $filehandle ); 
    }
    else {
        print STDERR "Unable to open $file_name for read: $!";
        return;    
    } 
    return $file_contents;
}

1;   

当我在EclipseMainModuleTest.t上右击并选择Run As Perl 时,它给出了以下输出:

代码语言:javascript
运行
复制
slurpFile() was successful!
not ok 1 - force the Utility Module call to fail
1..1
#   Failed test 'force the Utility Module call to fail'
#   at D:/Documents and Settings/[SNIP]/MainModuleTest.t line 13.
# Looks like you failed 1 test of 1.

当我右键单击同一个单元测试文件并选择Debug作为\ Perl本地时,它将给出以下输出:

代码语言:javascript
运行
复制
slurpFile() encountered a problem!
ok 1 - force the Utility Module call to fail
1..1

这显然是个问题。运行As和Debug应该会给出相同的结果,对吗?!!?

EN

Stack Overflow用户

回答已采纳

发布于 2009-11-23 19:00:16

导出和测试::MockModule都通过操作符号表来工作。这样做的事情并不总是能很好地结合在一起。在本例中,Test::MockModule在出口商已经将slurpFile导出到MainModule之后,正在将模拟版本的MainModule安装到MainModule中。MainModule使用的别名仍然指向原始版本。

要修复它,请将MainModule更改为使用完全限定的子例程名称:

代码语言:javascript
运行
复制
 my $file_contents = UtilityModule::slurpFile($file_name);

在调试器中这样做的原因是调试器还使用符号表操作来安装钩子。这些钩子必须以正确的方式和在正确的时间安装,以避免正常发生的不匹配。

有争议的是,它是一个bug (在调试器中),任何时候代码在那里的行为都不同于在调试器之外运行时的行为,但是当您有三个模块都在处理符号表时,这并不奇怪。

票数 1
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1759172

复制
相关文章

相似问题

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