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.