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 )