是否有一种简单的方法来设置用于perl测试的本地自包含Web服务器?

时间:2012-01-24 21:18:06

标签: perl unit-testing testing

我正在构建一个perl应用程序来存档简单的网页(即没有涉及查询字符串的静态页面)。我想编写测试来验证将访问远程文件的模块的功能。为了使测试具有自我依赖性,我正在寻找一个简单的,独立的Web服务器,测试脚本可以在本地使用。

下面是一个例子,概述了我正在尝试做的事情。我使用以下目录结构将其减少到最低限度:

./MirrorPage.pm
./t/001_get_url.t
./t/test-docroot/test-1.json

“./MirrorPage.pm”的内容:

package MirrorPage;

use Moose;
use LWP::Simple;
use namespace::autoclean;

sub get_url {

    my ($self, $url_to_get) = @_;

    ### grab the contents of the url
    my $url_data = get($url_to_get);

    ### return the contents.
    return $url_data;

}

__PACKAGE__->meta->make_immutable;

1;

“./t/001_get_url.t”的内容:

#!/usr/bin/perl 

use Modern::Perl;
use Test::More;
use MirrorPage;

    ### Start test www server on port 8123 here ###

my $t = new_ok('MirrorPage', undef, 'Create MirrorPage');

is(
    $t->get_url("http://localhost:8123/test-1.json"), 
    '{ testkey: "testvalue" }',
    "Verify the data."
);

    ### Kill test www server here ###

done_testing();

“./t/test-docroot/test-1.json”的内容:

{ testkey: "testvalue" }

目标是在“./t/001_get_url.t”中的相应评论位置启动并终止自包含的Web服务器。 Web服务器需要提供“./t/test-docroot”目录的内容作为其文档根目录。

考虑到所有这些:设置自包含Web服务器以提供用于在perl中进行测试的静态文件的最佳/最简单方法是什么?

6 个答案:

答案 0 :(得分:3)

我会在.t文件顶部附近模拟HTTP调用(如果你只想测试MirrorPage.pm):

my $mock = new Test::MockObject();
$mock->fake_module( 'LWP::Simple', get => sub { return '{ testkey: "testvalue" }' } );

答案 1 :(得分:2)

也许:

在顶部,使用HTTP::Server::Simple::Static分叉并执行一个简单的静态文件服务器,然后在底部终止子进程。

答案 2 :(得分:2)

LWP可以获取文件,因此您可以将$url_to_gethttp://...重写为file://...

答案 3 :(得分:2)

我强烈建议Mojolicious作为为客户端生成测试服务器的好方法。由于Mojolicious只是简单地将URL映射到子程序调用,因此很容易对服务器的功能进行非常精细的控制,因此您可以轻松地测试“如果服务器返回错误的响应/错误内容,我的客户端是否正常失败”超时“。由于设置和拆除服务器非常简单,使用fork()稍微聪明一点就可以让测试和服务器设置在同一个测试文件中。

答案 4 :(得分:1)

以下是我使用Net::HTTPServer提出的问题。基于" It’s OK to Ask and Answer Your Own Questions"的想法,我将其发布在此处以供评论/考虑。我所做的是以下内容:

首先,在以下位置创建一个新模块:" ./t / TestServer.pm"。该文件的内容是:

package TestServer;

use Moose;
use Net::HTTPServer;
use namespace::autoclean;

has 'server' => (
    is => "rw",
    isa => "Net::HTTPServer",
    default => sub { 
        Net::HTTPServer->new (
            port => 8123,
            docroot => "t/test-docroot"
        )
    }, 
);


sub BUILD {

    my $self = shift;

    ### Spin up the server.
    $self->server->Start();
    $self->server->Process();

}

### Close up the Moose package.
__PACKAGE__->meta->make_immutable;

1;

然后,更新测试" ./t / 001_get_url.t"文件通过fork使用它:

#!/usr/bin/perl 

use Modern::Perl;
use Test::More;
use MirrorPage;

### Fork for the server
my $pid = fork();

### Parent process. Holds the tests.
if($pid) {

    ### Make sure the server has a moment to startup
    sleep(2);

    my $t = new_ok('MirrorPage', undef, 'Create MirrorPage');

    is(
        $t->get_url("http://localhost:8123/test-1.json"), 
        '{ testkey: "testvalue" }',
        "Verify the data."
    );  
}

### Child process. Holds the server.
elsif(defined($pid)) {

    use lib "t/";
    use TestServer;

    my $svr = TestServer->new();

    exit; # Should never get here.

}

### Error out if necessary.
else {
    die "Can not fork child process.";
}


### Kill the server fork.
kill 1, $pid;

done_testing();

这对我来说效果很好。

答案 5 :(得分:-1)

虽然它是特定于操作系统的,但我确信Apache是​​你的答案。