PHP Developers Network

A community of PHP developers offering assistance, advice, discussion, and friendship.
 
Loading
It is currently Fri May 26, 2017 9:15 pm

All times are UTC - 5 hours




Post new topic Reply to topic  [ 4 posts ] 
Author Message
PostPosted: Wed Feb 20, 2013 12:35 am 
Offline
Forum Contributor
User avatar

Joined: Fri Oct 06, 2006 8:12 pm
Posts: 294
Hello!

I am migrating a legacy code base to something more testable. To level set, we have about a dozen classes that are fairly close to being testable (I think?), but we have around 140 functions that have not yet been migrated to become classes.

One of the issues we have run into is that the majority of the code passes around the $db object, which is in the global scope (yuck!).

I've read with interest here that this sort of thing is best resolved with Dependency injection. I've started down that path, and have manual DI for most, with the $db object being a parameter for the calls.

Now I want to go the next step, and get those files testable. I understand that the way to do that should be to use the DI container. My project has composer, so I am leaning towards Pimple, which is a really simple DI container.

But before I start hacking on that, are my assumptions/understandings correct? Is using a DI container going to make it easier to test my units of code? With the DI container, can I also move other objects (like configuration values) into the container, so we just need to pass the container into the units of code, and get both DB & configs?

Any guidance is greatly appreciated.


Top
 Profile  
 
PostPosted: Wed Feb 20, 2013 11:28 am 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13396
Location: New York, NY, US
I don't think a DI container will make you testing easier. A DI container helps by allowing you to predefine prerequisites to simplify creating object that inject or need dependencies injected. I think what you are looking for is Mocks. You can Mock your DB object and inject it giving you control without needing a database during testing.

PS - Congratulations on transitioning to classes and DI! And don't worry about common objects in the global scope (assuming register_globals is off as is normal).

_________________
(#10850)


Top
 Profile  
 
PostPosted: Thu Feb 21, 2013 10:29 pm 
Offline
Forum Contributor
User avatar

Joined: Fri Oct 06, 2006 8:12 pm
Posts: 294
Christopher wrote:
I don't think a DI container will make you testing easier.

Hmm! Interesting. I was having trouble understanding how I was going to test relatively simple classes that relied on $db being there. After your post, I read up on Mocking a DB, and it seems it would work for most of the simple cases. But then I stumbled onto the dbUnit element, and *woah*, I can build an entire fake database for testing?! Awesome.

Christopher wrote:
A DI container helps by allowing you to predefine prerequisites to simplify creating object that inject or need dependencies injected. I think what you are looking for is Mocks. You can Mock your DB object and inject it giving you control without needing a database during testing.

Well, to be honest, I didn't really know what I was looking for. I had some simple classes, and wanted to test them, but couldn't see past how to satisfy the $db need.

Christopher wrote:
PS - Congratulations on transitioning to classes and DI! And don't worry about common objects in the global scope (assuming register_globals is off as is normal).

Well, see, that assumption is entirely reasonable. Unfortunately, its NOT the case in the code base I am working on! Ack! We have a horrible bit of code that takes the post/get super globals and sticks them in the global scope. Its a mess, and that needs to go. But in the meantime, I want to do the right thing where I can. For the new code, I'm trying to make it clean and testable, and where possible, to eliminate globals.

So one of my questions remains. Can I use a DI container to store both config variables and a database object? Or is that worse than just having a $config and $db object?

Just curious.

Thanks again!


Top
 Profile  
 
PostPosted: Thu Feb 21, 2013 11:11 pm 
Offline
Site Administrator
User avatar

Joined: Wed Aug 25, 2004 7:54 pm
Posts: 13396
Location: New York, NY, US
The Phoenix wrote:
We have a horrible bit of code that takes the post/get super globals and sticks them in the global scope. Its a mess, and that needs to go. But in the meantime, I want to do the right thing where I can. For the new code, I'm trying to make it clean and testable, and where possible, to eliminate globals.
I would recommend wrapping the HTTP vars in a Request object that is a container for those value, plus support for dealing with post, get, ajax requests.
The Phoenix wrote:
So one of my questions remains. Can I use a DI container to store both config variables and a database object? Or is that worse than just having a $config and $db object?
Typically you would use some kind of Container object to hold the config variables. And a Registry to hold the $config and $db (and other) objects. It up to you whether you put the $config object and the $db object in a Registry and inject that, or inject the DI object and use it to instantiate objects where needed. Or a mix. DI objects are often used to instantiate objects that have complex wiring -- unlike the $config and $db objects to which you usually just pass an array or a few params.

_________________
(#10850)


Top
 Profile  
 
Display posts from previous:  Sort by  
Post new topic Reply to topic  [ 4 posts ] 

All times are UTC - 5 hours


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Jump to:  
Powered by phpBB® Forum Software © phpBB Group