In order to isolate some behavior in my SOAP::Lite tests, I wanted to ensure two things. First, I wanted to know that the SOAP request XML matched my expectations. Second, I wanted to ensure that the SOAP response XML was correctly parsed. In neither case did I want to actually make the round-trip to our customer's SOAP server.
package MOCK::SOAP::INTERFACE;
use Sub::Override;
use overload
'""' => \&request;
my $REQUEST; # this is the SOAP *request* XML
sub _mock_soap_interface
{
my $xml = shift; # this is the SOAP *response* XML
my $token = Sub::Override->new(
'SOAP::Lite::call',
sub {
my $self = shift;
$REQUEST = $self->serializer->envelope(method => shift(@_), @_);
return $xml;
}
);
bless $token => __PACKAGE__;
return $token;
}
sub request { return $REQUEST }
1;
Because overridden subs from Sub::Override are lexically scoped, the caller has to hold onto the returned token in order to keep it in scope. By blessing that token into my mocked class, I can then overload stringification and allow it to represent the SOAP request XML that &SOAP::Serializer::envelope returns. Then I write my test something like this:
sub test_my_soap : Test(2) {
my $xml = <<'END_XML';
END_XML
my %expected_circuits = (
# some data
);
my $expected_xml = # expected *request* XML
my $response = _mock_soap_interface($xml);
my $soap = MY::SOAP::Package->new;
my $circuits = $soap->get_circuits;
is_deeply(
$circuits,
\%expected_circuits
);
# quote response to break the overloading
is_xml("$response", $expected_xml);
}
Yeah, there's some hackish stuff there, but one thing I really like is that now, when you're reading the tests, the programmer is much more likely to remember to hold on to the returned token ($response). Still, it looks weird having a scalar who's value is going to change for no apparent reason. I can't say that I totally like this approach, but I was pretty durned pleased with myself.
I think that I might just have to offer some sort of overloading support for Sub::Override so that the returned token actually does something useful.