Added WebGUI::TestException and convert Shop/Pay.t to use it.
This commit is contained in:
parent
b8d9d38da6
commit
1658f3957d
2 changed files with 169 additions and 76 deletions
122
t/Shop/Pay.t
122
t/Shop/Pay.t
|
|
@ -18,11 +18,13 @@ use strict;
|
|||
use lib "$FindBin::Bin/../lib";
|
||||
use Test::More;
|
||||
use Test::Deep;
|
||||
use Test::Exception;
|
||||
use JSON;
|
||||
use HTML::Form;
|
||||
|
||||
use WebGUI::Test; # Must use this before any other WebGUI modules
|
||||
use WebGUI::Session;
|
||||
use WebGUI::TestException;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
# Init
|
||||
|
|
@ -31,7 +33,7 @@ my $session = WebGUI::Test->session;
|
|||
#----------------------------------------------------------------------------
|
||||
# Tests
|
||||
|
||||
my $tests = 27;
|
||||
my $tests = 18;
|
||||
plan tests => 1 + $tests;
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
|
|
@ -54,17 +56,15 @@ skip 'Unable to load module WebGUI::Shop::Pay', $tests unless $loaded;
|
|||
my $e;
|
||||
my $pay;
|
||||
|
||||
eval { $pay = WebGUI::Shop::Pay->new(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'new takes an exception to not giving it a session variable');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Must provide a session variable',
|
||||
got => '',
|
||||
expected => 'WebGUI::Session',
|
||||
),
|
||||
'new: requires a session variable',
|
||||
|
||||
throws_deeply ( sub { $pay = WebGUI::Shop::Pay->new(); },
|
||||
'WebGUI::Error::InvalidObject',
|
||||
{
|
||||
error => 'Must provide a session variable',
|
||||
got => '',
|
||||
expected => 'WebGUI::Session',
|
||||
},
|
||||
'new takes an exception to not giving it a session variable'
|
||||
);
|
||||
|
||||
$pay = WebGUI::Shop::Pay->new($session);
|
||||
|
|
@ -79,8 +79,6 @@ isa_ok($pay, 'WebGUI::Shop::Pay', 'new returned the right kind of object');
|
|||
isa_ok($pay->session, 'WebGUI::Session', 'session method returns a session object');
|
||||
is($session->getId, $pay->session->getId, 'session method returns OUR session object');
|
||||
|
||||
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
# addPaymentGateway
|
||||
|
|
@ -89,60 +87,45 @@ is($session->getId, $pay->session->getId, 'session method returns OUR session ob
|
|||
|
||||
my $gateway;
|
||||
|
||||
eval { $gateway = $pay->addPaymentGateway(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'addPaymentGateway croaks without a class');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
error => 'Must provide a class to create an object',
|
||||
),
|
||||
throws_deeply ( sub { $gateway = $pay->addPaymentGateway(); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => 'Must provide a class to create an object'
|
||||
},
|
||||
'addPaymentGateway croaks without a class',
|
||||
);
|
||||
|
||||
eval { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::NoSuchDriver'); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'addPaymentGateway croaks without a configured class');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply ( sub { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::NoSuchDriver'); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => 'The requested class is not enabled in your WebGUI configuration file',
|
||||
param => 'WebGUI::Shop::PayDriver::NoSuchDriver',
|
||||
),
|
||||
},
|
||||
'addPaymentGateway croaks without a configured class',
|
||||
);
|
||||
|
||||
eval { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::Cash'); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'addPaymentGateway croaks without a label');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply ( sub { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::Cash'); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => 'Must provide a label to create an object',
|
||||
),
|
||||
},
|
||||
'addPaymentGateway requires a label',
|
||||
);
|
||||
|
||||
|
||||
eval { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::Cash', 'JAL'); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'addPaymentGateway croaks without options to build a object with');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply ( sub { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::Cash', 'JAL'); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => 'You must pass a hashref of options to create a new PayDriver object',
|
||||
),
|
||||
},
|
||||
'addPaymentGateway croaks without options to build a object with',
|
||||
);
|
||||
|
||||
eval { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::Cash', 'JAL', {}); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'addPaymentGateway croaks without options to build a object with');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply ( sub { $gateway = $pay->addPaymentGateway('WebGUI::Shop::PayDriver::Cash', 'JAL', {}); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => 'You must pass a hashref of options to create a new PayDriver object',
|
||||
),
|
||||
},
|
||||
'addPaymentGateway croaks without options to build a object with',
|
||||
);
|
||||
|
||||
|
|
@ -170,11 +153,7 @@ my $defaultPayDrivers = {
|
|||
'WebGUI::Shop::PayDriver::Cash' => 'Cash',
|
||||
};
|
||||
|
||||
cmp_deeply(
|
||||
$drivers,
|
||||
$defaultPayDrivers,
|
||||
'getDrivers returns the default PayDrivers',
|
||||
);
|
||||
cmp_deeply( $drivers, $defaultPayDrivers, 'getDrivers returns the default PayDrivers');
|
||||
|
||||
#######################################################################
|
||||
#
|
||||
|
|
@ -182,14 +161,11 @@ cmp_deeply(
|
|||
#
|
||||
#######################################################################
|
||||
|
||||
eval { $drivers = $pay->getOptions(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'getOptions takes exception to not giving it a cart');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply( sub { $drivers = $pay->getOptions(); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => 'Need a cart.',
|
||||
),
|
||||
},
|
||||
'getOptions takes exception to not giving it a cart',
|
||||
);
|
||||
|
||||
|
|
@ -199,26 +175,20 @@ cmp_deeply(
|
|||
#
|
||||
#######################################################################
|
||||
|
||||
eval { $gateway = $pay->getPaymentGateway(); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::InvalidParam', 'getPaymentDriver throws an exception when no paymentGatewayId is passed');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply( sub { $gateway = $pay->getPaymentGateway(); },
|
||||
'WebGUI::Error::InvalidParam',
|
||||
{
|
||||
error => q{Must provide a paymentGatewayId},
|
||||
),
|
||||
},
|
||||
'getPaymentGateway throws exception without paymentGatewayId',
|
||||
);
|
||||
|
||||
eval { $gateway = $pay->getPaymentGateway('NoSuchThing'); };
|
||||
$e = Exception::Class->caught();
|
||||
isa_ok($e, 'WebGUI::Error::ObjectNotFound', 'getPaymentGateway thows exception when a non-existant paymentGatewayId is passed');
|
||||
cmp_deeply(
|
||||
$e,
|
||||
methods(
|
||||
throws_deeply( sub { $gateway = $pay->getPaymentGateway('NoSuchThing'); },
|
||||
'WebGUI::Error::ObjectNotFound',
|
||||
{
|
||||
error => q{payment gateway not found in db},
|
||||
id => 'NoSuchThing',
|
||||
),
|
||||
},
|
||||
'getPaymentGateway throws exception when called with a non-existant paymentGatewayId',
|
||||
);
|
||||
|
||||
|
|
|
|||
123
t/lib/WebGUI/TestException.pm
Normal file
123
t/lib/WebGUI/TestException.pm
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
package WebGUI::TestException;
|
||||
|
||||
use strict;
|
||||
|
||||
use Test::Builder;
|
||||
use WebGUI::Exception;
|
||||
use Sub::Uplevel qw( uplevel );
|
||||
|
||||
our @EXPORT = qw( throws_deeply );
|
||||
|
||||
=head1 NAME
|
||||
|
||||
Package WebGUI::TestException
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides a convenient way to test for thrown exceptions. The idea is based on Test::Exception, which
|
||||
does provide a means to test for a specific exception class, but cannot test attributes of that class, which is
|
||||
necessary in the WebGUI test suite. This module can do that.
|
||||
|
||||
=head1 CAVEATS
|
||||
|
||||
This module uses Sub::Uplevel. In Test::Exception some hocus pocus is being done with the caller() function. The
|
||||
functions _quiet_caller and _try_as_caller are directly copied from Test::Exception. I do not know why this
|
||||
hocuspocus is being in that module however, since doing 'eval { uplevel 1, $codeRef }' seems to work too. On my
|
||||
platform at least =). For the time being, I leave those subs in here so that they may be used. They are commented
|
||||
out by default, though.
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub _quiet_caller (;$) { ## no critic Prototypes
|
||||
my $height = $_[0];
|
||||
$height++;
|
||||
if( wantarray and !@_ ) {
|
||||
return (CORE::caller($height))[0..2];
|
||||
}
|
||||
else {
|
||||
return CORE::caller($height);
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub _try_as_caller {
|
||||
my $coderef = shift;
|
||||
|
||||
# local works here because Sub::Uplevel has already overridden caller
|
||||
local *CORE::GLOBAL::caller;
|
||||
{ no warnings 'redefine'; *CORE::GLOBAL::caller = \&_quiet_caller; }
|
||||
|
||||
eval { uplevel 3, $coderef };
|
||||
return $@;
|
||||
};
|
||||
|
||||
=head2 throws_deeply ( $codeRef, $expectClass, $fields, $message )
|
||||
|
||||
Executes the code ref and verifies it throws an exception of the given class with the given fields.
|
||||
|
||||
=head3 $codeRef
|
||||
|
||||
The code ref containing the code to be evalled.
|
||||
|
||||
=head3 $expectClass
|
||||
|
||||
The class name the thrown exception should have.
|
||||
|
||||
=head3 $fields
|
||||
|
||||
Hashref containg the exception fields and their expected values.
|
||||
|
||||
=head3 $message
|
||||
|
||||
The message that should be displayed by prove for this test.
|
||||
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------------
|
||||
sub throws_deeply {
|
||||
my $evalBlock = shift;
|
||||
my $expectClass = shift;
|
||||
my $fields = shift;
|
||||
my $message = shift;
|
||||
my $testBuilder = Test::Builder->new;
|
||||
|
||||
# Dunno why uplevel 1 might not work and why caller is redefined.
|
||||
# Copied _try_as_caller and _quiet_caller are from Test::Exception.
|
||||
# Uplevel 1 seems to work though.
|
||||
#_try_as_caller( $evalBlock );
|
||||
eval { uplevel 1, $evalBlock };
|
||||
|
||||
my $e = Exception::Class->caught();
|
||||
my $gotClass = ref $e;
|
||||
|
||||
# Check class
|
||||
unless ($gotClass eq $expectClass) {
|
||||
$testBuilder->ok(0, $message);
|
||||
$testBuilder->diag("Wrong class:\n\texpected : '$expectClass'\n\t got : '$gotClass'");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Check fields
|
||||
my $errors;
|
||||
foreach (keys %$fields) {
|
||||
my $result = $e->$_;
|
||||
|
||||
unless ( $result eq $fields->{$_} ) {
|
||||
$errors .= "'$_' => \n\texpected : '".$fields->{$_}."'\n\t got : '$result'\n";
|
||||
}
|
||||
}
|
||||
if ($errors) {
|
||||
$testBuilder->ok(0, $message);
|
||||
$testBuilder->diag("Fields do not match:\n$errors");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
# Test passed.
|
||||
$testBuilder->ok(1, $message);
|
||||
return 1;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue