package Aspect::Library::TestClass;
use strict;
use warnings;
use Carp;
use Test::Class;
use Aspect;
use base 'Aspect::Modular';
sub Test::Class::make_subject { shift->subject_class->new(@_) }
sub get_advice {
my ($self, $pointcut) = @_;
before {
my $context = shift;
my $self = $context->self; # the Test::Class object
return unless is_test_method_with_subject($context);
my (@params) = $self->subject_params if $self->can('subject_params');
my $subject = $self->make_subject(@params);
$self->init_subject_state($subject) if $self->can('init_subject_state');
$context->append_param($subject);
} call qr/::[a-z][^:]*$/ & $pointcut;
}
# true if we are in a test class, in a test method, and we can get a
# subject_class from the test class
# would be nice if we could somehow check for existence of test attribute
# on method
sub is_test_method_with_subject {
my $context = shift;
my $self = $context->self; # the Test::Class object
my @method = ($context->package_name, $context->short_sub_name);
return
UNIVERSAL::isa($self, 'Test::Class') &&
$self->_method_info(@method) &&
$self->can('subject_class');
}
1;
=head1 NAME
Aspect::Library::TestClass - give Test::Class test methods an IUT
(implementation under test)
=head1 SYNOPSIS
# append IUT to params of all test methods in matching packages
# place this in your test script
aspect TestClass => call qr/::tests::/;
=head1 SUPER
L<Aspect::Modular>
=head1 DESCRIPTION
Frequently my C<Test::Class> test methods look like this:
sub some_test: Test {
my $self = shift;
my $subject = IUT->new;
# send $subject messages and verify expected results
...
}
After installing this aspect, they look like this:
sub some_test: Test {
my ($self, $subject) = @_;
# send $subject messages and verify expected results
...
}
In the test class you must add one I<template method> to provide the
class of the IUT:
sub subject_class { 'MyApp::Person' }
=head1 REQUIRES
Only works with C<Test::Class> above version C<0.06_05>.
=head1 SEE ALSO
See the L<Aspect|::Aspect> pods for a guide to the Aspect module.
C<XUL-Node> tests use this aspect extensively.
=cut