App-SimpleBackuper
view release on metacpan or search on metacpan
local/lib/perl5/Test/Spec/Mocks.pm view on Meta::CPAN
actually are called. If they aren't, the mock will raise an exception which
causes your test to fail.
In this example, we are testing that C<read_line> is called once and only
once (the default for mocks).
it "returns true when a yes_or_no question is answered 'yes'" => sub {
my $console_mock = mock();
$console_mock->expects('read_line')
->returns("yes");
# $console_mock->read_line returns "yes"
ok( $asker->yes_or_no($console_mock, "Am I awesome?") );
};
If Asker's C<yes_or_no> method doesn't call C<read_line> on our mock exactly
one time, the test would fail with a message like:
expected read_line to be called exactly 1 time, but it was called 0 times
You can specify how many times your mock should be called with "exactly":
it "keeps asking until it gets an answer" => sub {
my @answers = (undef, "yes");
my $console_mock = mock();
$console_mock->expects('read_line')
->returns(sub { shift @answers })
->exactly(2);
# when console_mock is called the first time, it returns undef
# the second time returns "yes"
ok( $asker->yes_or_no($console_mock, "Do I smell nice?") );
};
If you want something more flexible than "exactly", you can choose from
"at_least", "at_most", "any_number" and others. See L</EXPECTATION ADJUSTMENT METHODS>.
=head2 Stubbing methods
Sometimes you want to override just a small subset of an object's behavior.
describe "The old audit system" => sub {
my $dbh;
before sub { $dbh = SomeExternalClass->get_dbh };
it "executes the expected sql" => sub {
my $sql;
$dbh->stubs(do => sub { $sql = shift; return 1 });
# $dbh->do("foo") now sets $sql to "foo"
# $dbh->quote still does what it normally would
audit_event($dbh, "server crash, oh noes!!");
like( $sql, qr/insert into audit_event.*'server crash, oh noes!!!'/ );
};
};
You can also stub class methods:
# 1977-05-26T14:11:55
my $event_datetime = DateTime->new(from_epoch => 0xdeafcab);
it "should tag each audit event with the current time" => sub {
DateTime->stubs('now' => sub { $event_datetime });
is( audit_timestamp(), '19770526.141155' );
};
=head2 Mocking methods
Mocked methods are to stubbed methods as mock objects are to stub objects.
it "executes the expected sql" => sub {
$dbh->expects('do')->returns(sub { $sql = shift; return 1 });
# $dbh->do("foo") now sets $sql to "foo"
# $dbh->quote still does what it normally would
audit_event($dbh, "server crash, oh noes!!");
like( $sql, qr/insert into audit_event.*'server crash, oh noes!!!'/ );
# if audit_event doesn't call $dbh->do exactly once, KABOOM!
};
=head1 CONSTRUCTORS
=over 4
=item stub()
=item stub($method_name => $result, ...)
=item stub($method_name => sub { $result }, ...)
=item stub({ $method_name => $result, ... })
Returns a new anonymous stub object. Takes a list of
C<$method_name>/C<$result> pairs or a reference to a hash containing the same.
Each C<$method_name> listed is stubbed to return the associated value
(C<$result>); or if the value is a subroutine reference, it is stubbed
in-place (the subroutine becomes the method).
Examples:
# A blank object with no methods.
# Gives a true response to ref() and blessed().
my $blank = stub();
# Static responses to width() and height():
my $rect = stub(width => 5, height => 5);
# Dynamic response to area():
my $radius = 1.0;
my $circle_stub = stub(area => sub { PI * $radius * $radius });
You can also stub more methods, just like with any other object:
my $rect = stub(width => 5, height => 5);
$rect->stubs(area => sub { my $self = shift; $self->width * $self->height });
=item $thing->stubs($method_name)
=item $thing->stubs($method_name => $result)
( run in 2.656 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )