PropelORM, Symfony 2 and Unit testing - php

I'm used to the habit of writing like this:
$results = SomeModelQuery::create()->filterByFoo('bar')->find();
However this does not scale for unit testing because I can't inject a mock object, i.e. I can't affect what data is returned. I'd like to use fixture data, but I can't.
Nor does it seem great to inject an object:
class Foo
{
public __construct($someModelQuery)
{
$this->someModelQuery = $someMOdelQuery;
}
public function doSthing()
{
$results = $this->someModelQuery->filterByFoo('bar')->find();
}
}
DI feels horrible. I have tens of query objects to mock and throw. Setting through constructor is ugly and painful. Setting using method is wrong because it can be forgotten when calling. And it feels painful to always for every single lib and action to create these query objects manually.
How would I elegantly do DI with PropelORM query classes? I don't want to call a method like:
$oneQuery = OneQuery::create();
$anotherQuery = AnotherQuery::create();
// ... 10 more ...
$foo = new Foo($oneQuery, $anotherQuery, ...);
$foo->callSomeFunctionThatNeedsThose();

In my opinion (and Martin Folowers's) there is a step between calling everything statically and using Dependency Injection and it may be what you are looking for.
Where I can't do full DI (Zend Framework MVC for example) I will use a Service Locator. A Service Layer will be the place that all your classes go to get there dependencies from. Think of it as a one layer deep abstraction for your classes dependencies. There are many benefits to using a Service Locator but I will focus on testability in this case.
Let's get into some code, here is are model query class
class SomeModelQuery
{
public function __call($method, $params)
{
if ($method == 'find') {
return 'Real Data';
}
return $this;
}
}
All it does is return itself unless the method 'find' is called. Then is will return the hard-coded string "Real Data".
Now our service locator:
class ServiceLocator
{
protected static $instance;
protected $someModelQuery;
public static function resetInstance()
{
static::$instance = null;
}
public static function instance()
{
if (self::$instance === null) {
static::$instance = new static();
}
return static::$instance;
}
public function getSomeModelQuery()
{
if ($this->someModelQuery === null) {
$this->someModelQuery = new SomeModelQuery();
}
return $this->someModelQuery;
}
public function setSomeModelQuery($someModelQuery)
{
$this->someModelQuery = $someModelQuery;
}
}
This does two things. Provides a global scope method instance so you can always get at it. Along with allowing it to be reset. Then providing get and set methods for the model query object. With lazy loading if it has not already been set.
Now the code that does the real work:
class Foo
{
public function doSomething()
{
return ServiceLocator::instance()
->getSomeModelQuery()->filterByFoo('bar')->find();
}
}
Foo calls the service locator, it then gets an instance of the query object from it and does the call it needs to on that query object.
So now we need to write some unit tests for all of this. Here it is:
class FooTest extends PHPUnit_Framework_TestCase
{
protected function setUp()
{
ServiceLocator::resetInstance();
}
public function testNoMocking()
{
$foo = new Foo();
$this->assertEquals('Real Data', $foo->doSomething());
}
public function testWithMock()
{
// Create our mock with a random value
$rand = mt_rand();
$mock = $this->getMock('SomeModelQuery');
$mock->expects($this->any())
->method('__call')
->will($this->onConsecutiveCalls($mock, $rand));
// Place the mock in the service locator
ServiceLocator::instance()->setSomeModelQuery($mock);
// Do we get our random value back?
$foo = new Foo();
$this->assertEquals($rand, $foo->doSomething());
}
}
I've given an example where the real query code is called and where the query code is mocked.
So this gives you the ability to inject mocks with out needing to inject every dependency into the classes you want to unit test.
There are many ways to write the above code. Use it as a proof of concept and adapt it to your need.

Related

Nested Objects in PHP

Likely this has already been asked, but nevertheless, here goes. This may fall under best practice or security... I'm not really sure.
In my application, I am using a nested object, that is called in the __construct() function. Sort of like this:
class user {
public $userID = NULL;
public $someObject = NULL;
public function __construct() {
$this->userID = getThisUser();
$this->someObject = new objectBuilder($this->userID);
}
public function getThisUser() {
// ...
}
}
class objectBuilder {
public $buriedVar = NULL;
public function __construct($uid = NULL) {
if( !isset($uid) ) {
$this->buriedVar = setTheObject($uid);
} else {
$this->buriedVar = setTheObject(0);
}
}
public function setTheObject($id) {
// ...
return "random string";
}
}
$tom = new user();
Obviously terrible outline here, but the point is, I can then call $tom->someObject->buriedVar and it'll return "random string".
While looking for a way to nest classes, I noticed no one recommends this as a method for storing objects inside of another object. I'm curious of a few things:
1) Is this insecure?
2) Are the vars inside the nested object exclusive to the call made inside $tom->__construct(), or if I create another object using new objectBuilder() is it overwriting the one inside $tom->someObject? I haven't noticed this, but am not sure how to test for that entirely.
3) Is there something else I'm missing? A best practice reason not to instantiate an object inside a class? I've been using it for years and it works great for what I've done. Is it a speed thing?
1) Is this insecure?
Not inherently, no.
2) Are the vars inside the nested object exclusive to the call made
inside $tom->__construct(), or if I create another object using new
objectBuilder() is it overwriting the one inside $tom->someObject? I
haven't noticed this, but am not sure how to test for that entirely.
This is a fundamental question between class and object. Objects are instances of a class and there can be multiple. The only things that would be overwritten are static properties and methods. You could test it like this:
<?php
$obj1 = new objectBuilder();
$obj2 = new objectBuilder();
if ($obj1 !== $obj2) {
echo "objects are not the same\n";
}
if ($obj1->buriedVar !== $obj2->buriedVar) {
echo "nested objects are not the same either\n";
}
$obj3 = new objectBuilder(1);
if ($obj1->buriedVar != $obj3->buriedVar) {
echo "even the values of two different buried vars with different values are different.\n";
}
if ($obj1->buriedVar == $obj2->buriedVar) {
echo "counter-example: nested variables with the same values set are similar.\n";
}
It helps to know the difference between equality and identity (see this SO post).
3) Is there something else I'm missing? A best practice reason not to
instantiate an object inside a class? I've been using it for years and
it works great for what I've done. Is it a speed thing?
You touched on it briefly. What you should know is that this is not scalable and is difficult to test.
Imagine you're creating a website for dogs.
<?php
class Bio
{
public function __construct()
{
$this->dog = new Dog('Terrier');
}
}
class Dog
{
private $animal = 'dog';
private $noise = 'woof!';
private $breed;
public function __construct($breed=null)
{
$this->setBreed($breed);
}
public function setBreed($breed)
{
$this->breed = $breed;
}
}
What if you want to add a new breed? Well... That's easy enough:
class Bio
{
// ...
public function __construct($breed)
{
$this->dog = new Dog($breed);
}
// ...
}
Cool! You've solved everything.
Except...
One day you want to create a section for cats, because one of your best writers also loves cats, and you sense an untapped market.
Uh oh...
You can refactor the code, of course. But you wrote it a long time ago. Now you have to go in and figure out where everything went. No big deal.. A bit annoying but you fixed it!
But now you have another problem. Turns out that the same author wants to add different traits to the breed. You're surprised this hasn't come up sooner but, hey, it's probably a good thing to have.
Now you need to go in to the Dog object, and the Cat object, and add traits.
Every single time.
On. Every. Bio.
After some reconfiguring, you've created something monstrous like this:
$article1 = new Bio('Terrier', 'dog', ['independent']);
$article2 = new Bio('Persian', 'cat', ['flat-faced']);
//... and so on, and so on
The next time the author asks for something, you fire her and then tear your hair out in a mad rage.
Or, from the beginning, you use Dependency Injection.
<?php
class Bio
{
private $animal;
public function __construct(AnimalInterface $animal)
{
$this->animal = $animal;
}
}
interface Animal
{
public function getType();
public function setBreed($breed);
public function getBreed();
public function setTraits(array $traits);
public function getTraits();
}
abstract class AbstractAnimal implements AnimalInterface
{
private $breed;
private $traits = [];
abstract public function getType();
public function setBreed($breed)
{
$this->breed = $breed;
}
public function getBreed()
{
return $this->breed;
}
public function setTraits(array $traits)
{
$this->traits = $traits;
}
public function getTraits()
{
return (array)$this->traits;
}
}
class Cat extends AbstractAnimal
{
public function getType()
{
return 'cat';
}
}
class Dog extends AbstractAnimal
{
public function getType()
{
return 'dog';
}
}
This pattern requires little to no editing after it has been created.
Why? Because you are injecting the object to nest into the class, rather than instantiating it in the object.
$bio1 = new Bio($dog); $bio2 = new Bio($cat); can always stay like this. Now you just edit the $dog and $cat objects. The added benefit is that these objects can be used anywhere.
But what about utility classes?
(This is where testability comes in. If you haven't worked with unit testing, I recommend reading up on it in the link to PHPUnit below. I'm not going to dwell on how that works as it's off topic).
Dependency Injection is well and good if you have classes that require customization. But what about utility classes that just house various functions?
class Utils
{
public function add($a, $b)
{
return $a + $b;
}
}
You might think that you can call this function safely from the constructor. And you can. However, one day you might create a log method in your Utils class:
public function log($msg)
{
exec("cat '$msg' > /tmp/log.txt");
}
This works just fine. However, when you run tests, your /tmp/log.txt file complains. "Invalid permissions!". When this method is run via your website, log.txt needs to be writeable by www-data.
You could just chmod 777 /tmp/log.txt, but that would mean everyone who has access to your server can write to that log. Additionally, you may not want to always write to the same log when you're testing as when you're navigating through the web interface (Personally, I would find it confusing and cluttering).
PHPUnit and other unit testing services allow you to mock various objects. The problem is that you have classes calling Utils directly.
You have to find a way to manually override the constructor. Look at PHPUnit's manual to find out why this maybe isn't ideal.
So if you're not using Dependency Injection, what do you do?
PHPUnit suggests, amongst other fixes, moving this Utils object instantiation to another method and then stubbing/mocking that method in your unit test (I want to emphasize that this is after recommending Dependency Injection).
So the next best?
public function __construct()
{
$this->init();
}
private function init()
{
$this->utils = new Utils;
}
Now when you unit test, you can create a fake init method and it will be called as soon as the class is created.
In conclusion, the way you are currently instantiating classes is not scalable or easily testable in many real world situations. While it may be all right in limited situations, it is better to get used to the DI (Dependency Injection) pattern, because it will save you lots of headaches in the future.

Call a method after __construct in finished

Basically I have a method which I need to run when the constructor is finished (the method is called persist() and it simply saves a key which was generated during the constructor into the session). It seems simple enough, and it works - at the end of __construct I make the call to $this->persist().
The problem is that this class is subclassed many times. This causes two issues.
One, that I must remember to make the call to persist() at the end of every single subclass's __construct method. Not a huge issue but it doesn't feel very OOP, I feel like I could be dealing with this in the parent class some how and that this would be better.
Two, if a subclass is subclassed (which it is), and the __construct methods chained (i.e. parent::__construct called), the persist() method will be getting fired multiple times, once for each time the class has been subclassed. It only needs to be called once, when all construction is complete. In this scenario it doesn't really break anything because when the persist method is called for the 2nd, 3rd time etc., it simply overwrites what was persisted before. But that isn't the point, because I just feel like there must be a better way and that there are scenarios out there that would not allow for the method to be called multiple times.
Is a factory method which constructs the object and then makes the call to persist on it the only way? I can go down this route but I am just wondering if there is a way to do it without, so that the method from the parent is always called after construction.
Here is some example code:
session_start();
is(!isset($_SESSION["Component"])) $_SESSION["Component"] = [];
abstract Class Component
{
private $id;
protected $key;
function __construct($id = NULL)
{
$this->id = $id;
$this->key = [];
$this->key["something"] = "SomeValue";
$this->persist(); // First call
}
protected function persist()
{
if($this->id !== NULL) $_SESSION["Component"][$this->id] = $this->key;
}
}
Class SomeComponent extends Component
{
function __construct($id = NULL)
{
parent::__construct($id);
$this->key["something-else"] = "SomeOtherValue";
$this->persist(); // Second call
}
}
Class SomeSpecialistComponent extends SomeComponent
{
function __construct($id = NULL, $key = [])
{
parent::__construct($id);
$this->key = array_merge($this->key, $key);
$this->persist(); // Third call
}
}
$my_component = new SomeSpecialistComponent(1, ["example" => true]);
Only trick I found to get something similar (except I wanted to execute things before and not after) is using a parent class with an abstract method as a new constructor :
abstract class RequireThings {
public function __construct() {
$this->constructAndPersist();
$this->persist();
}
abstract function constructAndPersist();
// You could also set this function in your children classes by the way.
public function persist() {
echo ' Then I persist!';
}
}
class UsingPersist extends RequireThings {
public function constructAndPersist() {
echo 'I do my things first.';
}
}
$class = new UsingPersist();
Would output :
I do my things first. Then I persist!
If I got your problem right, it should be enough to avoid problems you are facing.
The main downside of this solution is that you have to use a new function which is supposed to be your new constructor for this type of classes. That's why I set the __constructPersist as abstract, it forces the behavior as wanted.
I would argue in favor of the factory method, mostly because you're doing real work in the constructor. Remove the call where work is being done in the constructors ($this->persist) and place it in the factory:
class ComponentFactory
{
const SOME_COMPONENT = 'component';
const SOME_SPECIALIST_COMPONENT = 'specialist_component';
public static function make($type, $id, $key = null)
{
switch($type) {
case self::SOME_COMPONENT:
$component = new SomeComponent($id);
break;
case self::SOME_SPECIALIST_COMPONENT:
$component = new SomeSpecialistComponent($id, $key);
break;
}
$component->persist();
return $component;
}
}
$component = ComponentFactory::make(ComponentFactory::SOME_COMPONENT, 42);
$specialist = ComponentFactory::make(
ComponentFactory::SOME_SPECIALIST_COMPONENT,
43,
[
'something' => 'SomeValue',
'something-else' => 'SomeOtherValue',
]
);
According to Miško Hevery (author of AngularJS and agile coach at Google) these are the warning signs of doing too much work in the constructor:
new keyword in a constructor or at field declaration
Static method calls in a constructor or at field declaration
Anything more than field assignment in constructors
Object not fully initialized after the constructor finishes (watch
out for initialize methods)
Control flow (conditional or looping logic) in a constructor
CL does complex object graph construction inside a constructor
rather than using a factory or builder
Adding or using an initialization block
just create another function that you'll call before $this->persist and override that in your subclasses instead of the constructor

PHP Dependency Injection and Loose Coupling

I am pondering a few different approaches here and would really appreciate some input! I am considering the two choices below. There are 2 things going on there I have questions on.
Is it preferred to inject the dependencies into the constructor of the main "container" class, or to instead create new instances inside the container class?
In the second example, the class' dependencies are injected via constructor and then maintained within via a property of the class. Then when the methods (route(), render()) are called, the dependencies are called from within. I began with this approach, but am now favoring something more along the lines of the first example. I think the first example is preferable, but are there any benefits to using the DI approach in the second example?
There really is no need to store anything in the class as a property. I can probably rearrange everything to use that technique without much trouble, and I think I like it better. This way I can also move all of the of work out of the constructors, and simply access everything via method later. Am I on the right track here?
class App
{
private $config;
private $router;
private $renderer;
public function __construct(IConfig $config, IRouter $router, IRenderer $renderer)
{
$this->config = $config;
$this->router = $router;
$this->renderer = $renderer;
$this->run();
}
public function run()
{
$data = $this->router->route(new Request, $config->routes);
$this->renderer->render($data);
}
}
class App
{
private $config;
private $router;
private $renderer;
public function __construct()
{
$this->config = new Config;
$this->run();
}
public function run()
{
$this->router = new Router(new Request, $config->routes);
$this->router->route();
$this->renderer = new Renderer($this->router->getData());
$this->renderer->render();
}
}
It is better to inject dependencies into the constructor.
Creating instances within the constructor creates a tight coupling between the two classes. With a constructor with a clear signature like
public function __construct(IConfig $config, IRouter $router, IRenderer $renderer)
I can immediately tell what this component needs to do it's job.
Given a constructor like
public function __construct();
There is no clue what the component needs to function. It creates a strong coupling to specific implementations of your each your router, your request and to your renderer, none of which are apparent until you dig down into the guts of your class.
In summary the first approach is well documented, extendable and testable.
the second approach is opaque, highly coupled, and not easily testable.
While Orangepill makes a good point, I thought I'd chip in, too. I tend to define my constructors with a clear constructor, too, but I don't expect the required objects to be passed when creating an instance.
Sometimes, you create an instance that retrieves data either from a DB, or some sort of Http request. In your case, the first example expects three dependencies to be passed, but who's to say that you'll always need all three of them?
Enter Lazy-Loading. The code sample below is quite lengthy, but it is (IMO) well worth looking into. If I use a service, I don't want to load all dependancies unless I'm sure I'll be using them. That's why I defined the constructor so that I can create an instance in either one of the following ways:
$foo = new MyService($configObj);
$bar = new MyService($configObj, null, $dbObj);//don't load curl (yet)
$baz = new MyService($configObj, $curlObj);//don't load db (yet)
If I wanted to run some test, I can still inject the dependencies when constructing my instance, or I can rely on a test-config object or I could use the setDb and setCurl methods, too:
$foo->setCurl($testCurl);
Sticking to the first way of constructing the instance, I can safely say that, if I only invoke the getViaCurl method, the Db class will never be loaded.
The getViaDb method is a bit more elaborate (as is the getDb method). I don't recommend you working with methods like that, but it's just to show you how flexible this approach can be. I can pass an array of parameters to the getViaDb method, which can contain a custom connection. I can also pass a boolean that'll control what I do with that connection (use it for just this one call, or assign the connection to the MyService instance.
I hope this isn't too unclear, but I am rather tired, so I'm not all too good at explaining this stuff ATM.
Here's the code, anyway... it should be pretty self explanatory.
class MyService
{
private $curl = null;
private $db = null;
private $conf = null;
public function __construct(Config $configObj, Curl $curlObj = null, Db $dbObj = null)
{
$this->conf = $configObj;//you'll see why I do need this in a minute
$this->curl = $curlObj;//might be null
$this->db = $dbObj;
}
public function getViaCurl(Something $useful)
{
$curl = $this->getCurl();//<-- this is where the magic happens
return $curl->request($useful);
}
public function getViaDb(array $params)
{
if (isset($params['custom']))
{
$db = $this->getDb($params['custom'], $params['switch']);
}
else
{//default
$db = $this->getDb();
}
return $db->query($params['request']);
}
public function getCurl()
{//return current Curl, or load default if none set
if ($this->curl === null)
{//fallback to default from $this->conf
$this->curl = new Curl($this->conf->getSection('CurlConf'));
}
return $this->curl;
}
public function setCurl(Curl $curlObj)
{//inject after instance is created here
if ($this->curl instanceof Curl)
{//close current connection
$this->curl->close();
}
$this->curl = $curlObj;
}
public function setDb(Db $dbObj)
{
if ($this->db instanceof Db)
{//commit & close
$this->db->commit();
$this->db->close();
}
$this->db = $dbObj;
}
//more elaborate, even:
public function getDb(Db $custom = null, $switch = false)
{
if ($custom && !!$swith === true)
{
$this->setDb($custom);
return $this->db;
}
if ($custom)
{//use custom Db, only this one time
return $custom;
}
if ($this->db === null)
{
$this->db = new Db($this->conf->getSection('Db'));
}
return $this->db;
}
}

Is it bad to mock the object being tested in a unit test?

Here is the class I am unit testing. Currently I am testing the doSomething function:
class FooClass {
public function doSomething( $user ) {
$conn = $this->getUniqueConnection( $user->id );
$conn->doSomethingDestructive();
}
private function getUniqueConnection( $id ) {
return new UniqueConnection( $id );
}
}
As you can see, the doSomething function gets a new instance of UniqueConnection (a class I am not testing here) based on a property of the argument it receives. The problem is that UniqueConnection:: doSomethingDestructive method is something I cannot call during tests due to its... destructiveness. So I would like to stub/mock the UniqueConnection rather than use a real one.
I don't see any way to inject my mocked UniqueConnection. I would make the UniqueConnection a constructor argument for FooClass but, as you can see, a new one gets created based on the parameter to the doSomething function and all the unique ids it may be called with are not known ahead of time.
My only option that I can see is to test a mock of FooClass instead of FooClass itself. Then I would replace the getUniqueConnection function with one that returns a mock/stub. This seems bad to test an mock, but I don't see any way to achieve what I am after otherwise. UniqueConnection is a third party vendor library and cannot be modified.
You could make a UniqueConnectionFactory, and pass an instance of that to FooClass. Then you have
private function getUniqueConnection( $id ) {
return $this->uniqueConnectionFactory->create( $id );
}
In general, this is one of the benefits of using a factory - you keep the new operator out of the class, which allows you to more easily vary the object being created.
Like Rambo Coder said, it's a matter of doing too much in your class. I wouldn't go as far as wanting to create a Factory, especially if you'll only ever create an instance of one specific class. The simplest solution would be to invert the responsibility of creating the UniqueConnection:
<?php
class FooClass {
public function doSomething( UniqueConnection $connection ) {
$connection->doSomethingDestructive( );
}
}
Pass a mock when you're testing, pass a new UniqueConnection( $user->id ) in the real code..
Until you can take the time to refactor the code to use a factory as rambo coder recommends, you can use a partial mock to return a non-destructive unique connection. When you find yourself in this position, it usually means the class under test has more than one responsibility.
function testSomething() {
$mockConn = $this->getMock('UniqueConnection');
$mockConn->expects($this->once())
->method('doSomethingDestructive')
->will(...);
$mockFoo = $this->getMock('FooClass', array('getUniqueConnection'));
$mockFoo->expects($this->once())
->method('getUniqueConnection')
->will($this->returnValue($mockConn));
$mockFoo->doSomething();
}
Creating classes in a way that it can support different modes of execution is very important in some cases. One of these cases is what you are asking for.
Create your classes to support various modes. For example
Class Connection {
private $mode;
public function setMode($mode) {
$this -> $mode = $mode;
}
}
Now, your doSomethingDestructive can act as per the execution mode.
public function doSomethingDestructive() {
if($this -> mode === "test") { //if we are in a test mode scenario
//Log something
// Or just do some logging and give a message
} else {
// do what it was suppose to do
}
}
Next time, when you are testing the class, you dont have to worry about that destructive function doing something destruction accidentally.
public function doSomething( $user ) {
$conn = $this->getUniqueConnection( $user->id );
$conn -> setMode("test"); //Now we are safe
$conn->doSomethingDestructive(); //But the Testing is still being Ran
}
In this case what you want is not a mock object, but a testing subclass. Break your $conn->doSomethingDestructive(); into a method, then subclass FooClass as TestFooClass and override the new method in the subclass. Then you can test using the subclass without getting the unwanted destructive behavior.
For example:
class FooClass {
public function doSomething( $user ) {
$conn = $this->getUniqueConnection( $user->id );
$this->connDoSomethingDestructive($conn);
}
protected function connDoSomethingDestructive($conn) {
$conn->doSomethingDestructive();
}
private function getUniqueConnection( $id ) {
return new UniqueConnection( $id );
}
}
class TestFooClass extends FooClass {
protected function connDoSomethingDestructive() {
}
private function getUniqueConnection( $id ) {
return new MockUniqueConnection( $id );
}
}

Unit testing with mocks (PHP)

I have a class like:
class Foo {
function getCurrentBar() {
$model = Query::findByPk($this->getSession()->get('current_bar')); // Pseudocode...
return $model;
}
}
So basically there's one bar at a time in my application and it is stored in the session as an integer. I frequently call a helper function which will find the model instance, it makes a db query. There is caching as well, but that won't matter now.
My question is this: how do I unit test with this? There are classes that I test that need this. I guess I could alter the session to contain the id but then it means I need to have a corresponding model in the database.
Would the best approach be to add a method setCurrentBar() just for unit testing purposes? Then I could mock a bar object and set it and it will be used for all unit tests. Does that make sense?
The answer is indeed dependency injection, but the dependency you want to control is the source of bars, not the bar itself.
class Foo {
private $query;
function __construct($query)
{
$this->query = $query;
}
function getCurrentBar() {
$model = $this->query->findByPk($this->getSession()->get('current_bar')); // Pseudocode...
return $model;
}
}
So in your production code you have
$query = new Query() // assuming findByPk() is made a normal non-static method
$realFoo = new Foo($query);
but for unit testing...
$testFoo = new Foo(new MockQuery());
where MockQuery is a mock version of your Query class which returns mock bars.
You could try using dependency injection.
Pass the Bar instance to the Foo constructor
class Foo
{
private _bar;
function __construct (Bar $bar)
{
$this->_bar = $bar;
}
public function getCurrentBar()
{
return $this->_bar;
}
}
Then you can inject your mock Bar Object when you run your test.
You could also choose to test a partial mock object, as an interim until a DI system is in place.
class Foo {
function getCurrentBar() {
$model = $this->getQueryResult($this->getSession()->get('current_bar')); // Pseudocode...
return $model;
}
function getQueryResult($queryParams)
{
return Query::findByPk($queryParams);
}
}
Then do a test that looks a bit like this...
$myObjectToTest = $this->getMock('Foo', array('getQueryResult'), array(), '', true, true, true);
$myObjectToTest->expects($this->once())
->method('getQueryResult')
->with($whateverTheQueryParametersAre)
->will($this->returnValue($someResult));
$myObjectToTest->getCurrentBar();

Categories