Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

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.

share|improve this question

3 Answers 3

Agreeing to what @verdammelt ,mocking is where we define an expectation for a given input which means we are defining both the input as well as output. If we mock web services similarly, it may be prove costly later.

So we decided not to mock our web services and expose it to actual & garbage values. With this approach we can check how the web service reacts and if any exceptions are thrown.

This was my personal experience with mocking web services. Hope it helps

share|improve this answer

Your test harness needs to have direct access to the data store to run queries developed for the particular test to validate the results and cleanup after the test.

Relying on other functions within the system being tested even if those functions aren't being tested in the same test means those functions must be 100% correct to the assumptions your test is making and in my opinion that can be an unsafe assumption.

I don't believe you can unit test your wrapper - it's just that and doesn't have any independent logic.

share|improve this 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.

share|improve this answer

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.