简体   繁体   中英

What are the good frameworks for unit-testing and mock objects in Perl?

What frameworks and tools would you recommend for unit-testing and mock objects in Perl?

I have an existing Perl application, that mainly does database access, reading and writing files. The application is basically a batch job type of application, it reads in bunch of stuff from files and database and writes a bunch of new files and some stuff to database.

The application currently does not have any unit-test, but I'd like refactor application to have good unit tests.

What frameworks and tools would you recommend for unit-testing and mocking objects? For example something similar to Hamcrest and JMock of Java?

Also, are there any good BDD (Behaviour Driven Development) based testing frameworks for Perl?

In terms of test frameworks, I like to use Test::Class , which lets you set up nice unit test hierarchies in a manner similar to JUnit. The linked documentation gives a pretty good overview, though if you're not already familiar with Perl testing conventions, check out the documentation for Test::Simple and TAP , which is the standard output format for Perl tests.

For mocking, there is Test::Mock::Class , which is useful for setting up mock classes for libraries outside your direct control, like CPAN modules that your application relies on.

There is also the excellent Test::MockDBI which provides special facilities for mocking your database stuff.

Just to add a little bit about BDD bit because friedo answer I think covers everthing else.

Have a quick look at this Perlmonks discussion Behavior Driven Development: suggested tools for perl?

I think some tools which may point you in right direction:

Also see this SO question: Can you review my Perl rewrite of Cucumber?

Hope some of this helps.

/I3az/

Lately, with MooseX::Declare , I've been using "real objects" as mock objects.

Say you have a database driver that does an interface like this:

role Database {
    requires 'connect';
    requires 'query';
};

Then you have code like this that uses the Database:

class FooPage {
    has 'database' => (
        is       => 'ro',
        does     => 'Database',
        required => 1,
    );

    method get_foo() {
        $self->database->query({ foo => 42 });
    }

    method render_page(Str $user) {
        "Hello, $user.  Here is a foo for you: ". $self->get_foo;
    }
};

Now you want to test this:

use Test::More tests => 2;
use MooseX::Declare;

my $fake_database = class with Database {
    has 'data' => ( is => 'ro', isa => 'HashRef' );
    has 'connected' => ( is => 'rw', isa => 'Bool' );

    method connect() { $self->connected(1) }
    method query(HashRef $query) { $self->data->{$query->{foo}} }
};

my $test_database = $fake_database->name->new(
    data => {
        42 => 'OH HAI',
    },
};

my $foo_page = FooPage->new( database => $test_database );
is $foo_page->get_foo, 'OH HAI', 'got correct foo';
is $foo_page->render_page('jrockway'),
   'Hello, jrockway.  Here is a foo for you: OH HAI',
 'got rendered page';

Notice how you have concise syntax, but the full power of a "real" Moose class as your mock object. Convenient, and infinitely flexible.

(These are just examples... it could also be something much better.)

它不是一个框架,但最好的测试书籍之一是优秀的Perl测试:开发人员的笔记本 ,它也提供了Perl测试框架的建议,例如Test::More

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM