development (in)action

Testing Web-Service Clients With Zend Framework

It seems the majority of my time these days is spent writing clients to consume all of the fantastic web-services that people and companies create for us, we are the fortunate beneficiaries of these peoples efforts. Developing clients to consume web-services has at times the additional sticky points that other efforts development may not, there may be a  case were we can not afford to make actual real-live calls to an endpoint (no test sandbox, monetary charges or we simply do not possess actual access to the endpoint.) In these case and most especially while testing we do not want to make ‘real-live’ calls to the endpoint. It is not nor should it be the purpose of our tests to test the endpoints performance. A functional test of an endpoint is unrelated to the client libraries we have developed and wish to test and as such should never be dependent on the endpoint for testing its performance characteristics.

I hate reinventing the wheel for common problems that many very smart people have already solved and solved well; which is why most of my personal development is based on a framework, specifically Zend Framework.  The Zend Framework has great support for testing in a vast majority of its components and for the purpose of this article we will be utilizing the Zend_Http_Client for the examples.

The strategy for testing web-services is to simply mock the Zend_Http_Client_Adapter_* the request employs; each test will decide in the setup of the test what status code will be sent, what headers and what the body content will contain. The approach I take with this is creating static files within a fixtures directory ( tests/fixtures/http/someEndpoint.200.xml),  making an effort to identify each documents purpose and how it should be used in the test. I may include in these files the any number of unwanted errors, malformed documents entities in an attempt to expose weaknesses in my handling, (this is especially handy when bugs are discovered that are undocumented in the provider API or unforeseen in development):

Examples of the http response status and content-type should reside in strings similar to the following (note additional headers may be appended following this forming the expected document preamble:

The test belows demonstrates the key points of setting up the test; the setup method provisions the class being tested which in this case extends the Zend_Http_Client. This provides a method setAdapter; with this method we are able to provide the Zend_Http_Client_Adapter_Test for use in our testing. We will test one method, accountStatus and are only demonstrating one test case testApiSuccess within this test case we read in the fixtures file contents and append them to the responseHeader we declared in the #setUp method; this string is passed to the call:$this->Api->getAdapter()->setResponse($fixture); and becomes the desired result of our web-service call. This process of mock returns affords us the ability to generate infinite result sets across a varying range of expected or anticipated failure scenarios.