Reputation: 12933
I have the following class I want to test:
<?php
namespace Freya\Component\PageBuilder\FieldHandler;
use Freya\Component\PageBuilder\FieldHandler\IFieldHandler;
/**
* Used to get a set of non empty, false or null fields.
*
* The core purpose is to use this class to determine that A) Advanced Custom Fields is installed
* and B) that we get back a set of fields for a child page.
*
* The cavete here is that this class requires you to have child pages that then have Custom Fields that
* you want to display on each of those pages. getting other page information such as content, title, featured image
* and other meta boxes is left ot the end developer.
*
* @see Freya\Component\PageBuilder\FieldHandler\IFieldHandler
*/
class FieldHandler implements IFieldHandler {
/**
* {@inheritdoc}
*
* @return bool
*/
public function checkForAFC() {
return function_exists("register_field_group");
}
/**
* {@inheritdoc}
*
* @param $childPageID - the id of the child page who may or may not have custom fields.
* @return mixed - Null or Array
*/
public function getFields($childPageId) {
$fieldsForThisPage = get_fields($childPageId);
if (is_array($fieldsForThisPage)) {
foreach ($fieldsForThisPage as $key => $value) {
if ($value === "" || $value === false || $value === null) {
unset($fieldsForThisPage[$key]);
}
}
return $fieldsForThisPage;
}
return null;
}
}
I can test all of this but one thing I want to do is stub the get_fields()
function to say you will return this type of array to then be used how ever the rest of the function uses it, which in this case is looping through it.
The part I don't know how to do in php is stub a function that's being called and then say you will return x.
So how do I stub get_fields
?
Upvotes: 2
Views: 3027
Reputation: 24576
You can use a trick here with the unqualified function name get_fields()
. Since you don't use the fully qualified function name \get_fields()
PHP will first try to find the function in the current namespace and then fall back to the global function name.
For the definition of qualified and unqualified, see: http://php.net/manual/en/language.namespaces.basics.php (it's similar to absolute and relative filenames)
So what you have to do is define the function in the namespace of the class, together with your test case, like this:
namespace Freya\Component\PageBuilder\FieldHandler;
function get_fields()
{
return ['X'];
}
class FieldHandlerTest extends \PHPUnit_Test_Case
{
...
}
Upvotes: 1
Reputation: 3967
You cen define such function in global namespace. Take a look at the following example:
namespace {
function getFields($pageId) {
return array($pageId);
}
}
namespace MyNamespace {
class MyClass
{
public function foo(){
var_dump(getFields(5));
}
}
$obj = new MyClass();
$obj->foo();
}
And here is the output:
array(1) {
[0]=>
int(5)
}
The only issue is that this function will exist till end of script. To solve this problem you can use the tearDown method together with runkit library:
http://php.net/manual/en/function.runkit-function-remove.php
that allows you to remove user defined functions. Unfortunatelly this library does not exist on Windows so there you won't be able to remove the definition and may consider running tests in isolation.
Edit: You can also consider using this library (it also depends on runkit): https://github.com/tcz/phpunit-mockfunction
Upvotes: 2