PHPUnit's getMock($classname, $mockmethods) creates a new object based on the given class name and lets me change/test the behavior of the methods I specified.
I long for something different; it's changing the behavior of methods of an existing object - without constructing a new object.
Is that possible? If yes, how?
When thinking about the problem I came to the conclusion that it would be possible by serializing the object, changing the serialized string to let the object be instance of a new class that extends the old class plus the mocked methods.
I'd like some code for that - or maybe there is such code already somewhere.
While it would certainly be possible to create the to-be-mocked object again, it's just too complicated to do it in my test. Thus I don't want to do that if I don't really really really have to. It's a TYPO3 TSFE instance, and setting that up once in the bootstrapping process is hard enough already.
I know this answer is rather late, but I feel for future viewers of this question there now exists a simpler solution (which has some drawbacks, but depending on your needs can be much easier to implement). Mockery has support for mocking pre-existing objects with what they call a "proxied partial mock." They say that this is for classes with final methods, but it can be used in this case (although the docs do caution that it should be a "last resort").
$existingObjectMock = \Mockery::mock($existingObject);
$existingObjectMock->shouldReceive('someAction')->andReturn('foobar');
It acts by creating a proxy object which hands all method calls and attribute gets/sets to the existing object unless they are mocked.
It should be noted, though, that the proxy suffers from the obvious issue of failing any typechecks or typehints. But this can be usually avoided, because the $existingObject can still be passed around. You should only use the $existingObjectMock when you need the mock capabilities.
Not all pre-existing code can be tested. Code really needs to be designed to be testable. So, while not exactly what you're asking for, you can refactor the code so that the instantiation of the object is in a separate method, then mock that method to return what you want.
class foo {
function new_bar($arg) { return new bar($arg); }
function blah() {
...
$obj = $this->new_bar($arg);
return $obj->twiddle();
}
}
and then you can test it with
class foo_Test extends PHPUnit_Framework_TestCase {
function test_blah() {
$sut = $this->getMock('foo', array('new_bar', 'twiddle'));
$sut->expects($this->once())->method('new_bar')->will($this->returnSelf());
$sut->expects($this->once())->method('twiddle')->will($this->returnValue('yes'));
$this->assertEquals('yes', $sut->blah());
}
}
Let me start of by saying: Welcome to the dark side of unit testing.
Meaning: You usually don't want to do this but as you explained you have what seems to be a valid use case.
runkit
What you can do quite easily, well not trivial but easier than changing your application architecture, is to change class behavior on the fly by using runkit
runkit_method_rename(
get_class($object), 'methodToMock', 'methodToMock_old'
);
runkit_method_add(
get_class($object), 'methodToMock', '$param1, $param2', 'return 7;'
);
runkit::method_add
and after the test to a method_remove and the rename again. I don't know of any framework / component that helps you with that but it's not that much to implement on your own in a UglyTestsBaseTest extends PHPUnit_Framework_TestCase.
Well...
If all you have access to is a reference to that object (as in: The $x in $x = new Foo();) i don't know of any way to say: $x, you are now of type SomethingElse and all other variables pointing to that object should change too.
I'm going to assume you already know things like testing your privates but it doesn't help you because you don't have control over the objects life cycle.
The php test helpers extension
Note: the Test-Helper extension is superseded by https://github.com/krakjoe/uopz
What also might help you out here is: Stubbing Hard-Coded Dependencies using the php-test-helpers extension that allows you do to things like Intercepting Object Creation.
That means while your application calls $x = new Something(); you can hack PHP to make it so that $x then contains an instance of YourSpecialCraftedSomething.
You might create that classing using the PHPUnit Mocking API or write it yourself.
As far as i know those are your options. If it's worth going there (or just writing integration / selenium tests for that project) is something you have to figure out on your own as it heavily depends on your circumstances.
Related
I have a bone to pick with dependency injection. It seems like such a simple concept has led to a lot of confusion amongst many, and the 'right' way to it seems to spiral out of control in terms of complexity. In keeping things really simple I just want to know:
Is it good practice if I use standard functions to register my dependencies, like this:
function someObject() {
return new someObject();
}
And can I pass parameters?
function someObject($param1) {
return new someObject($param1);
}
Finally how about using a simple custom container class:
class Dependencies {
function someObject($param1) {
return new someObject($param1);
}
}
And using it:
class SomeClass {
public function __construct(Dependencies $dependencies) {
$this->dependencies = $dependencies
}
public function methodNeedsDependency() {
$param1 = 'one';
$task = $this->dependencies->someObject($param1);
}
}
I guess what I'm asking is, is this a decent attempt at a very simple implementation of a DIC? Or are there some underlying major issues bubbling under the surface?
Thanks!
If SomeClass is a factory, designed to create some instance with some exact config given, then yes, we could say this is very simple implementation of DIC.
Issues here? Well, let's say You want to create someObject with other constructor params.
Solutions:
Create another SomeClass factory that will pass other params. It's redundant solution that also mixes two application layers ( config with object creation layer ).
Parametrize methodNeedsDependency with params that will be passed to someObject. It's something that allows You to postpone in code config creation.
and last but the most proper way: DIC should be flexible, should allow You to create any service instances with any dependencies, and all of configuration should be stored in configuration layer. Separation of concerns - try to make DIC unaware of what object type is creating. Just let him make objects that You described somewhere else.
There are a lot of other issues also, like for example what if You would like to have only one instance of given class for whole DIC ( it's easy to "if" it, but that's another workaround to proper solution ) or what with circular references.
This discussion can go on and on with other issues about architecture in general, like "services should be stateless" what makes it unnecesary to have more then one, but answer to your question are those 3 points. Of course remember it's not ultimate-mega-hiper answer for DIC. It's just my way of seeing it ;-)
I recently started learning the basics of OOP in PHP.
I am new to a whole lot of concepts.
In the traditional procedural way of doing things, if I had a repetitive task, I wrote a function and called it each time.
Since this seems to be a regular occurence, I created a small library of 5-10 functions, which I included in my procedural projects and used.
In OOP, what is the valid way of using your functions and having them accessible from all objects?
To make things closer to the real world, I created a thumbnail class, that takes an image filename as an argument and can perform some operations on it.
In procedural programming. when I had a function for creating thumbnails, I also had a function to create a random md5 string, check a given folder if said string existed, and repeat if it did, so I could generate a unique name for my thumbnails before saving them.
But if I wanted to generate another unique name for another purpose, say saving a text file, I could call that function again.
So, long story short, what is the valid OOP way to have the method randomise_and_check($filename) (and all other methods in my library) accessible from all the objects in my application?
Great question. The first thing you want to do is identify the primary objects you will be working with. An easy way to do this is to identify all the nouns related to your project. In your example it sounds like you will be working with images and strings, from this we can create two classes which will contain related attributes (functions, member variables, etc). And as you wisely mentioned, we need to ensure that the algorithms you are converting into OOP can be called from any context, so we try to keep them abstract as possible (within reason).
So for your specific situation I would suggest something like:
// Good object reference, abstract enough to cover any type of image
// But specific enough to provide semantic API calls
class Image
{
// Using your example, but to ensure you follow the DRY principle
// (Don't repeat yourself) this method should be broken up into two
// separate methods
public static function randomise_and_check($fileUri)
{
// Your code here
....
// Example of call to another class from within this class
$hash = String::generateHash();
}
}
// Very abstract, but allows this class to grow over time, by adding more
// string related methods
class String
{
public static function generateHash()
{
return md5(rand());
}
}
// Calling code example
$imageStats = Image::radomise_and_check($fileUri);
There are several other approaches and ideas that can be employed, such as whether or not to instantiate objects, or whether we should create a parent class from which we can extend, but these concepts will become evident over time and with practice. I think the code snippet provided should give you a good idea what you can do to make the jump from procedural to OOP. And, as always, don't forget to read the docs for more info.
-- Update --
Adding an OOP example:
class Image
{
protected $sourceUri;
public function setSourceUri($sourceUri)
{
$this->sourceUri = $sourceUri;
}
public function generateThumb()
{
return YourGenerator::resize($this->getSourceUri);
}
}
$image = new Image();
$image->setSourceUri($imageUri);
$thumbnail = $image->generateThumbnail();
The way I see it, you have two options:
Don't worry about cramming yourself into OOP and just make them standard, global functions in some utilities.php file you include wherever you want to use it. This is my preferred method.
If you take the more OOP approach, you could make them static functions ("methods") in some utilities class. From the PHP documentation:
<?php
class Foo {
public static function aStaticMethod() {
// ...
}
}
Foo::aStaticMethod();
$classname = 'Foo';
$classname::aStaticMethod(); // As of PHP 5.3.0
?>
Create an (abstract) Util-class with static functions:
example from my Util class:
abstract Class Util{
public static function dump($object){
echo '<pre class=\"dump\">' . print_r($object, true) . '</pre>';
}
}
How to use:
<?
$object = new Whatever();
//what's in the object?
Util::dump($object);
?>
For a beginner, OOP development is not all that different from procedural (once you master the basic concepts it gets quite a bit different, but that's not important to learning the basics).
You deal in OO concepts all the time, you just don't realize it. When you click on a file in your file manager, and manipulate that file.. you're using Object Oriented concepts. The file has attributes (size, type, read-only, etc..) and things you can do with it (open, copy, delete).
You just apply those concepts to development by creating objects that have properties and things you can do with it (methods).
In the OOP world, you don't typically make things available to everything else. OOP is all about "encapsulation", which is limiting access to only that which is needed. Why would you make a "haircut" method available to an orange juice object? You wouldn't. You only make the "haircut" method available to objects that need haircuts.
Writing reusable OO software is very difficult. Even professionals can't get it right a lot of the time. It requires a mixture of experience, training, practice, and frankly luck in some cases.
You should read about Dependency Injection as it seems to apply to your specific problem. Basically, you have an object that depends on some abstraction, maybe the "Image Library" functionality. In your controller, you would create an instance of the "Image Library" object and inject that dependency into whatever other objects required it.
That is, you need to stop thinking on the global scope altogether. Instead, you have to compartmentalize functionailties in a sane way and tie them together. Basically, objects should only know about as little as they need to know (also look up Law of Demeter and SOLID). I reiterate, this is tough to do correctly, and most of the time you can still have an application that works beautifully even if it's done incorrectly.
If you want to be very strict about this you should apply this line of thinking to everything, but if you have a function that wraps something very simple like return isset($_POST[$key]) ? $_POST[$key] : $default; I see no real harm in creating a global function for that. You could create an HttpPost wrapper class, but that is overkill in most circumstances IMO.
The short answer: use ordinary function. OOP encourages you to think about data and associated routines, using static functions instead of ordinary does not make your program more object-oriented. Following the single programming paradigm is not practical, combine them when you see that this will make your program cleaner.
My code is located here: https://github.com/maniator/SmallFry
Should I make it so that that the App class does not have to use static functions but at the same time be able to set and set variables for the app from anywhere?
Or should I keep it how it is now with App::get and App::set methods?
What are the advantages and disadvantages of both?
How would I accomplish that 1st task if I was to undertake it?
Related Question
Sample code:
//DEFAULT TEMPLATE
App::set('APP_NAME', 'SmallVC');
//END DEFAULT TEMPLAT
//
//DEFAULT TEMPLATE
App::set('DEFAULT_TEMPLATE', 'default');
//END DEFAULT TEMPLATE
//DEFAULT TITLE
App::set('DEFAULT_TITLE', 'Small-VC');
//END DEFAULT TITLE
//LOGIN SEED
App::set('LOGIN_SEED', "lijfg98u5;jfd7hyf");
//END LOGIN SEED
App::set('DEFAULT_CONTROLLER', 'AppController');
if(App::get('view')){
$template_file = $cwd.'/../view/'.App::get('view').'/'.App::get('method').'.stp';
if(is_file($template_file)){
include $template_file;
}
else {
include $cwd.'/../view/missingview.stp'; //no such view error
}
}
else {
App::set('template', 'blank');
include $cwd.'/../view/missingfunction.stp'; //no such function error
}
I think you have a feeling that static is bad. What I am posting may seem fairly crazy as it is a massive change. At the very least hopefully it presents a different idea of the world.
Miško Hevery wrote static methods are a death to testability.
I like testing, so for that reason I don't use them. So, how else can we solve the problem? I like to solve it using what I think is a type of dependency injection. Martin Fowler has a good but complicated article on it here.
For each object at construction I pass the objects that are required for them to operate. From your code I would make AppController become:
class AppController
{
protected $setup;
public function __construct(array $setup = array())
{
$setup += array('App' => NULL, 'Database' => NULL);
if (!$setup['App'] instanceof App)
{
if (NULL !== $setup['App'])
{
throw new InvalidArgumentException('Not an App.');
}
$setup['App'] = new App();
}
// Same for Database.
// Avoid doing any more in the constructor if possible.
$this->setup = $setup;
}
public function otherFunction()
{
echo $this->setup['App']->get('view');
}
}
The dependancies default to values that are most likely (your default constructions in the if statements). So, normally you don't need to pass a setup. However, when you are testing or want different functionality you can pass in mocks or different classes (that derive from the right base class). You can use interfaces as an option too.
Edit The more pure form of dependency injection involves further change. It requires that you pass always pass required objects rather than letting the class default one when the object isn't passed. I have been through a similar change in my codebase of +20K LOC. Having implemented it, I see many benefits to going the whole way. Objects encapsulation is greatly improved. It makes you feel like you have real objects rather than every bit of code relying on something else.
Throwing exceptions when you don't inject all of the dependencies causes you to fix things quickly. With a good system wide exception handler set with set_exception_handler in some bootstrap code you will easily see your exceptions and can fix each one quickly. The code then becomes simpler in the AppController with the check in the constructor becoming:
if (!$setup['App'] instanceof App)
{
throw new InvalidArgumentException('Not an App.');
}
With every class you then write all objects would be constructed upon initialisation. Also, with each construction of an object you would pass down the dependencies that are required (or let the default ones you provide) be instantiated. (You will notice when you forget to do this because you will have to rewrite your code to take out dependencies before you can test it.)
It seems like a lot of work, but the classes reflect the real world closer and testing becomes a breeze. You can also see the dependencies you have in your code easily in the constructor.
Well, if it was me, I would have the end goal of injecting the App dependency into any class (or class tree) that needs it. That way in testing or reusing the code you can inject whatever you want.
Note I said reuse there. That's because it's hard to re-use code that has static calls in it. That's because it's tied to the global state so you can't really "change" the state for a subrequest (or whatever you want to do).
Now, on to the question at hand. It appears that you have a legacy codebase, which will complicate things. The way I would approach it is as follows:
Create a non-static version of the app class (name it something different for now) that does nothing but proxy its get/set calls to the real app class. So, for example:
class AppProxy {
public function set($value) {
return App::set($value);
}
}
For now, all it has to do is proxy. Once we finish getting all the code talking to the proxy instead of the static app, we'll make it actually function. But until then, this will keep the application running. That way you can take your time implementing these steps and don't need to do it all in one big sweep.
Pick a main class (one that does a lot for the application, or is important) that you easily control the instantiation of. Preferably one that you instantiate in only one place (in the bootstrap is the easiest). Change that class to use Dependency Injection via the constructor to get the "appproxy".
a. Test this!
Pick another class tree to work on, based on what you think will be most important and easiest.
a. Test!!!
If you have more calls to App::, Go to #3
Change the existing App class to be non-static.
a. Test!!!!!!!!!!
Remove the AppProxy and replace with App in the dependency injectors. If you did it right, you should only have one place to change to make this switch.
Pat yourself on the back and go get a drink, cause you're done.
The reason that I segmented it out like this is that once a step is completed (any step), you can still ship working software. So this conversion could take literally months (depending on the size of your codebase) without interrupting business as usual...
Now, once you're done, you do get some significant benefits:
Easy to test since you can just create a new App object to inject (or mock it as needed).
Side effects are easier to see since the App object is required wherever it could be changed.
It's easier to componentize libraries this way since their side effects are localized/
It's easier to override (polymorphism) the core app class if it's injected than if it's static.
I could go on, but I think it's pretty easy to find resources on why statics are generally bad. So that's the approach I would use to migrate away from a static class to an instance...
If you don't want to have static functions but global access from everywhere WITHOUT passing the object to the places where it is actually needed then you pretty much can only use one thing:
A global variable
So you are not really better of doing that. But that is the only thing i can think of that would fulfill your requirements.
If you App object is something like an application config a first possible step would be to pass it to the objects that need it:
class Login {
public function __construct() {
$this->_login_seed = App::get('LOGIN_SEED');
self::$_ms = Database::getConnection();
}
changes into:
class Login {
public function __construct(App $app) {
$this->_login_seed = $app->get('LOGIN_SEED');
self::$_ms = Database::getConnection();
}
Basic setup. I have a classA instance which is a subclass of classX ... On construction (or sometime else), I want it to load another class classB which is also a subclass of classX and replace itself with classB in situ. Sort of like a factory, but one that replaces itself transparently. If need be, I can wrap classB with classA if there is a way to (at runtime) change the subclass of an object.
Currently I am using classA::__call() to emulate MRO magic, but is seems very inelegant. This needs to be done transparently to the caller of classA/B so that to the outside world, it isn't aware that classA has replaced itself with classB after construction (or anywhere else for that matter).
I know PHP can be a bit thin when doing things like this ... I am suspecting we can't, but it would be handy for my situation.
Also, 5.3 but ideally (yuck) 5.2/x
Thanks in advance (wishing I was coding in Python)
Ok, I've taken an interest in this question because I've reached the point where I'd like to discover the exact limits of PHP, including little hacks like this. Hopefully, I'll make sense this late at night and a few beers in me. Because of the ugly hackishness, I'm actually expecting to be downvoted.
Obviously, you can't do $this = $that. You also can't change the global variable you're currently trying to make into an object while it's being constructed, and attempting to do so will be ignored. As Charles said earlier, this can't be reasonably done. Not with clone, not serialize(), nothing within __construct().
So, unreasonably if you want $a to first become an object of class A, then convert mid-creation to class B, try this pseudo method: You'll have to call __construct of class A twice in a row. First time to handle construction of class A. Second time to complete the object converting it to class B. Class A handles the first half of construction, and class B the second half:
class A {
function __construct() {
$args = func_get_args(); // just to tell us the first round of __construct already occured
if (array_key_exists(0, $args) AND $args[0]) {
$GLOBALS['a'] = new B($GLOBALS['a']);
// stop because "reconstruction" has stopped. Nothing else you can do to $a in this scope.
$this->aprop2 = "yay";
// Seriously, stop. Don't bother putting more code at this point, you're wasting your time. Consider $a 'converted and returned' already.
}
// build on an object of class a here
}
}
class B {
function __construct($var) {
// maybe you'd like to do something with old $a? If so, here's $var for you
// continue constructing where A left off.
}
}
$a = new A(); // object of class A
$a->__construct(true); // object of class B
Maybe instead make another method of class A named more importantly sounding, which does the same thing to convert the global $a into object of class B, just so it doesn't look so stupid as my example. In other words, you're probably already doing it as best as PHP allows.
Edit: Really though, the above is nothing more than $a = new A(); $a = new B($a);. For better code readability and maintainability, you may want not to use my example and instead opt to implement a factory or handler class that creates and juggles these objects for you. I found a brief and insightful www.ibm.com article explaining the concept of factories how they are applied in PHP. Maybe conceptually, you want a static class that acts like a cd changer, and this is where Return by Reference - to work with a variable reference to the object in any scope - and Variable Objects (ref: midir's comments on that page) - to dynamically set or work with the object - comes in handy.
This is not currently possible in PHP...
Without doing stupid things.
If every instance of the object is a reference, and those references can be found in $GLOBALS, and the object knows what every one of those instances is called, you could replace each and every reference of the old object with your new object. The outside world won't know the difference.
This is, however, a spectacularly awful idea. Using __call magic is probably the least insane way of accomplishing your goal.
Edit: There's always runkit, which will let you do things like add and remove methods from classes. However, it's a PECL extension and might not even work correctly...
I currently have a method within my class that has to call other methods, some in the same object and others from other objects.
class MyClass
{
public function myMethod()
{
$var1 = $this->otherMethod1();
$var2 = $this->otherMethod2();
$var3 = $this->otherMethod3();
$otherObject = new OtherClass();
$var4 = $otherObject->someMethod();
# some processing goes on with these 4 variables
# then the method returns something else
return $var5;
}
}
I'm new to the whole TDD game, but some of what I think I understood to be key premises to more testable code are composition, loose coupling, with some strategy for Dependency Injection/Inversion of Control.
How do I go about refactoring a method into something more testable in this particular situation?
Do I pass the $this object reference to the method as a parameter, so that I can easily mock/stub the collaborating methods? Is this recommended or is it going overboard?
class MyClass
{
public function myMethod($self, $other)
{
# $self == $this
$var1 = $self->otherMethod1();
$var2 = $self->otherMethod2();
$var3 = $self->otherMethod3();
$var4 = $other->someMethod();
# ...
return $var5;
}
}
Also, it is obvious to me that dependencies are a pretty big deal with TDD, as one has to think about how to inject a stub/mock to the said method for tests. Do most TDDers use DI/IoC as a primary strategy for public dependencies? at which point does it become exaggerated? can you give some pointers to do this efficiently?
These are some good questions... let me first say that I do not really know JS at all, but I am a unit tester and have dealt with these issues. I first want to point out that JsUnit exists if you are not using it.
I wouldn't worry too much about your method calling other methods within the same class... this is bound to happen. What worries me more is the creation of the other object, depending on how complicated it is.
For example, if you are instantiating a class that does all kinds of operations over the network, that is too heavy for a simple unit test. What you would prefer to do is mock out the dependency on that class so that you can have the object produce the result you would expect to receive from its operations on the network, without incurring the overhead of going on the network: network failures, time, etc...
Passing in the other object is a bit messy. What people typically do is have a factory method to instantiate the other object. The factory method can decide, based on whether or not you are testing (typically via a flag) whether or not to instantiate the real object or the mock. In fact, you may want to make the other object a member of you class, and within the constructor, call the factory, or make the decision right there whether or not to instantiate the mock or the real thing. Within the setup function or within your test cases you can set special conditions on the mock object so that it will return the proper value.
Also, just make sure you have tests for your other functions in the same class... I hope this helps!
Looks like the whole idea of this class is not quite correct. In TDD your are testing classes, but not methods. If a method has it own responsibility and provides it's own (separate testable) functionality it should be moved to a separate class. Otherwise it just breaks the whole OOP encapsulation thing. Particularly it breaks the Single Responsibility Principle.
In your case, I would extract the tested method into another class and injected $var1, $var2, $var3 and $other as dependencies. The $other should be mocked, as well any object which tested class depends on.
class TestMyClass extends MyTestFrameworkUnitTestBase{
function testMyClass()
{
$myClass = new MyClass();
$myClass->setVar1('asdf');
$myClass->setVar2(23);
$myClass->setVar3(78);
$otherMock = getMockForClassOther();
$myClass->setOther($otherMock);
$this->assertEquals('result', $myClass->myMethod());
}
}
Basic rule I use is: If I want to test something, I should make it a class. This is not always true in PHP though. But it works in PHP in 90% of cases. (Based on my experience)
I might be wrong, but I am under the impression that objects/classes should be black boxes to their clients, and so to their testing clients (encapsulating I think is the term I am looking for).
There's a few things you can do:
The best thing to do is mock, here's one such library: http://code.google.com/p/php-mock-function
It should let you mock out only the specific functions you want.
If that doesn't work, the next best thing is to provide the implementation of method2 as a method of an object within the MyClass class. I find this one of the easier methods if you can't mock methods directly:
class MyClass {
function __construct($method2Impl) {
$this->method2Impl = $method2Impl;
}
function method2() {
return $this->method2Imple->call();
}
}
Another option is to add an "under test" flag, so that the method behaves different. I don't recommend this either - eventually you'll have differing code paths and with their own bugs.
Another option would be to subclass and override the behaviors you need. I -really- don't suggest this since you'll end up customizing your overridden mock to the point that it'll have bugs itself :).
Finally, if you need to mock out a method because its too complicated, that can be a good sign to move it into its own object and use composition (essentially using the method2Impl technique i mentioned above).
Possibly, this is more a matter of single responsibility principle being violated, which is feeding into TDD issues.
That's a GOOD thing, that means TDD is exposing design flaws. Or so the story goes.
If those methods are not public, and are just you breaking apart you code into more digestable chunks, honestly, I wouldn't care.
If those methods are public, then you've got an issue. Following the rule, 'any public method of a class instance must be callable at any point'. That is to say, if you're requiring some sort of ordering of method calls, then it's time to break that class up.