package Test::Magpie::Spy; BEGIN { $Test::Magpie::Spy::VERSION = '0.04'; } # ABSTRACT: A look into the invocation history of a mock for verifaciotn use Moose; use namespace::autoclean; use aliased 'Test::Magpie::Invocation'; use List::AllUtils qw( first ); use Moose::Util qw( find_meta ); use Test::Builder; use Test::Magpie::Util qw( extract_method_name ); with 'Test::Magpie::Role::HasMock'; has 'invocation_counter' => ( default => sub { sub { @_ > 0 } }, is => 'bare', ); my $tb = Test::Builder->new; sub BUILDARGS { my $self = shift; my %args = @_; if (defined(my $times = delete $args{times})) { $args{invocation_counter} = ref($times) eq 'CODE' ? $times : sub { @_ == $times }; } return \%args; } our $AUTOLOAD; sub AUTOLOAD { my $self = shift; my $method = extract_method_name($AUTOLOAD); my $observe = Invocation->new( method_name => $method, arguments => \@_ ); my $meta = find_meta($self); my $mock = $meta->get_attribute('mock')->get_value($self); my $invocations = find_meta($mock)->get_attribute('invocations') ->get_value($mock); my @matches = grep { $observe->satisfied_by($_) } @$invocations; my $invocation_counter = $meta->get_attribute('invocation_counter') ->get_value($self); $tb->ok($invocation_counter->(@matches), sprintf("%s was invoked the correct number of times", $observe->as_string)); } 1; __END__ =pod =encoding utf-8 =head1 NAME Test::Magpie::Spy - A look into the invocation history of a mock for verifaciotn =head1 DESCRIPTION Spy objects allow you to look inside a mock and verify that certain methods have been called. You create these objects by using C from L. Spy objects do not have a public API as such; they share the same method calls as the mock object itself. The difference being, a method call now checks that the method was invoked on the mock at some point in time, and if not, fails a test. You may use argument matchers in verification method calls. =head1 AUTHOR Oliver Charles =head1 COPYRIGHT AND LICENSE This software is copyright (c) 2010 by Oliver Charles . This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself. =cut