When mocking a method in PHPUnit produces a “cannot be configured” error

When mocking an object in PHPUnit testing, if you receive the following error even when the function name  is correct. For example, if mocking non-custom Doctrine Repositories (i.e. no SomeEntityRepository class) will cause:

Error:
Trying to configure method “getUser” which cannot be configured because it does not exist, has not been specified, is final, or is static

This occurs on a PHPUnit_Framework_MockObject_MockObject object when using the PHPUnit_Framework_TestCase and PHPUnit_Framework_MockObject_MockBuilder.

In the case of mocking Doctrine find calls, often this error means $methodName parameter in the getMockBuilder($methodName) function is incorrect. For example the following code is incorrect:

// Produces error
$itemRepoMock = $this
  ->getMockBuilder('AppBundle\Entities\ItemRepository')
  ->method('find')
  ->disableOriginalConstructor()
  ->getMock();
$itemRepoMock
  ->expects($this->any())
  ->method('find')
  ->will($this->returnValue($itemMock));

Here you need to specify Doctrine’s base EntityRepository class instead, so:
AppBundle\Entities\ItemRepository
becomes
Doctrine\ORM\EntityRepository
The same example:

// Fixed
$itemRepoMock = $this
  ->getMockBuilder('Doctrine\ORM\EntityRepository')
  ->method('find')
  ->disableOriginalConstructor()
  ->getMock();
$itemRepoMock
  ->expects($this->any())
  ->method('find')
  ->will($this->returnValue($itemMock));

As a defined ItemRepository does not exist, neither dies its find function, even though you can usually use the inferred name.

Advertisements

Using Twig’s default() filter to avoid “Variable some_var does not exist”

References to undefined variables are a common cause of web pages not displaying when using Twig. A simple mention of an undefined variable can cause 500 errors:

{{ some_var }}

Variable some_var does not exist in..

Whilst turning strict_variables off in the twig config will obviously hide the error and is best for production, during development hiding errors can ultimately making spotting bugs harder. A better solution is using Twig’s default() filter like so:

{{ some_var|default("") }}

This will print the variable if it exists or nothing if it is not defined.
For if statements and loops, there are 3 choices:

  1. The default() filter:
  2. {% if some_var|default(false) %}some text{% endif %}
  3. The fine grain but hideously verbose control of defined:
  4. {% if some_var is defined and some_var %}some text{% endif %}
  5. The empty filter:
  6. {% if some_var is not empty %}some text{% endif %}

There are also lots of other useful tests, filters and functions that Twig provides out of the box, check out their documentation pages for more info. Hope this helps. Please like and share if it does 🙂

Checkout Specific Git Branches in Composer.json

Composer allows different branches of a Git repository to be checked out for use as a third party library. To do so first add the git repository to your composer.josn file:

 "repositories": [
     {
         "type": "vcs",
         "url": "git@bitbucket.org:org/repo.git"
     }
 ]

 

Now the repository is known, add the branch to the composer.json require section:

"require": {
    "org/repo": "dev-branch1"
}

 

You can even choose a specfic commit:

"require": {
    "org/repo": "dev-branch1#ec457d0a974c48d5685a7efa03d137dc8bbde7e3"
}

 

Examples

As explained on the getcomposer.org website, login details can be provided to access private repositories. For example, using ssh:

{
    "require": {
        "org/repo": "dev-branch1"
    },
    "repositories": [
        {
            "type": "composer",
            "url": "ssh2.sftp://bitbucket.org",
            "options": {
                "ssh2": {
                    "username": "composer",
                    "pubkey_file": "/home/username/.ssh/id_rsa.pub",
                    "privkey_file": "/home/username/.ssh/id_rsa"
                }
            }
        }
    ]
}

 

Or using an SSL certificate key:

{
    "require": {
        "org/repo": "dev-branch1"
    },
    "repositories": [
        {
            "type": "vcs",
             "url": "https://bitbucket.org:org/repo.git",
            "options": {
                "ssl": {
                    "local_cert": "/home/username/.ssl/composer.pem"
                }
            }
        }
    ]
}

 

Or using HTTP Basic authentication:

{
    "require": {
        "org/repo": "dev-branch1"
    },
    "repositories": [
        {
            "type": "vcs",
            "url": "https://username:password@bitbucket.org/com/repo.git"
        }
    ]
}

 

This provides fairly good SSL encrypted security, although it’s a good idea to remove the username & password credentials from the Git repository and instead place them in a file named auth.json within the COMPOSER_HOME directory, as such:

{
    "https://bitbucket.org": {
        "http-basic": {
            "bitbucket.org": {
                "username": "username",
                "password": "password"
            }
        }
    }
}

 

You can also specify HTTP headers directly, which enables our preferred method for stateless authentication, JWT (Java Web Tokens):

{
    "repositories": [
        {
            "type": "vcs",
            "url": "https://bitbucket.org/com/repo.git",
            "options":  {
                "http": {
                    "header": [
                        "authorization: authenticated.jwt.token"
                    ]
                }
            }
        }
    ]
}

 

Conclusion

As can be seen from the above examples, Composer enables a flexible range of options in regards to the selection and integration of Git repositories along with their respective branches and versions.

Doctrine createQueryBuilder() – EntityManager vs. EntityRepository

EntityRepository and EntityManager have slightly different versions of the createQueryBuilder() function. Whereas the EntityManager’s version takes no arguments, EntityRepository’s version expects an ‘$alias‘ parameter. What is going on?!

The EntityRepository class wraps the EntityManager’s call, as such:

From /lib/Doctrine/ORM/EntityRepository.php

The function’s phpdoc reveals the reasoning behind the parameter count differences, EntityRepository returns a version of createQueryBuilder() customised for itself. We no longer need to specify the primary table we’re selecting from. Instead we must supply an $alias parameter which would usually be later supplied to the from() function.

Also note the above means all columns are selected from the entity by default.

Doctrine not autoloading classes even when they exist

Using doctrine with silex is a great way to combine the power of a good ORM with the efficiency of a micro-framework, however doctrine – well-known for its step learning curve – can be even more frustrating for new users when used outside of the big well-integrated frameworks (e.g. Symfony & Zend.

One problem in particular can be with autoloading. First namespaces need to be taken care of, with a matching directory structure. The doctrine documentation helps with this.

An error which can be particularly troublesome is:

{"statusCode":500,"message":"Class 'SomeClass' does not exist"}

Even after creating the class and placing it in the correct place.

If you using composer, you may simply need to run “composer update” from the command line (wherever the project’s composer.json file is located) to reload the autoloading classes. Until this is done doctrine just won’t be able to see the file and will keep on complaining that it does not exist, even though it does.

Also, remember autoloading is case-sensitive so make sure you have this correct and that there aren’t old copies of wrongly cased files in the same directory.