Php – unit/integration testing web service proxy client

integration-testsPHPunit testingweb services

I'm rewriting a PHP client/proxy library that provides an interface to a SOAP-based .Net webservice, and in the process I want to add some unit and integration tests so future modifications are less risky.

The work the library I'm working on performs is to marshall the calls to the web service and do a little reorganizing of the responses to present a slightly more -object-oriented interface to the underlying service.

Since this library is little else than a thin layer on top of web service calls, my basic assumption is that I'll really be writing integration tests more than unit tests – for example, I don't see any reason to mock away the web service – the work that's performed by the code I'm working on is very light; it's almost passing the response from the service right back to its consumer.

Most of the calls are basic CRUD operations: CreateRole(), CreateUser(), DeleteUser(), FindUser(), &ct.

I'll be starting from a known database state – the system I'm using for these tests is isolated for testing purposes, so the results will be more or less predictable.

My question is this: is it natural to use web service calls to confirm the results of operations within the tests and to reset the state of the application within the scope of each test? Here's an example:

One test might be createUserReturnsValidUserId() and might go like this:

public function createUserReturnsValidUserId() {
   // we're assuming a global connection to the service
   $newUserId = $client->CreateUser("user1");
   assertNotNull($newUserId);
   assertNotNull($client->FindUser($newUserId);
   $client->deleteUser($newUserId);
}

So I'm creating a user, making sure I get an ID back and that it represents a user in the system, and then cleaning up after myself (so that later tests don't rely on the success or failure of this test w/r/t the number of users in the system, for example). However this still seems pretty fragile – lots of dependencies and opportunities for tests to fail and effect the results of later tests, which I definitely want to avoid.

Am I missing some options of ways to decouple these tests from the system under test, or is this really the best I can do?

I think this is a fairly general unit/integration testing question, but if it matters I'm using PHPUnit for the testing framework.

Best Answer

Unfortunately I am not familiar with PHP or PHPUnit; so I apologize if this answer may end up not so useful.

I have experience of trying to do testing in the style you are suggesting and I found it to quickly become a large problem. Integration tests which integrate with the DB must ensure that either after every test, or before ever test that the db is in a known good state. Without this you will get lots of false results. To do it can be an annoying problem. In either case it will take time and be slow.

If your layer is in fact a thin layer which takes a some data from the web and push it to the db layer after (possibly) some modification, validation, etc - I would strongly suggest decoupling it from both the web and from the DB. Mock both ends in your tests. Your tests will be small and fast. Test separately your db layer to ensure it does the right thing when your translation layer tells it to do something.

Since I am not familiar with PHP or PHPUnit I can't help you on how to decouple and mock these items, unfortunately.

Related Topic