user101289
user101289

Reputation: 10422

Mock class in phpunit

I'm finally getting into PHP unit testing (yeah better late than never!)

I have a Utility class that does a few things including authenticating a user's access against a webservice. The Utility::authenticate method takes a Settings object, which contains the username etc. that are checked by authenticate.

So in my test, I mock a Settings object like this:

$settings = $this->getMock('Settings', array('getSettings'));

$settings->method('getSettings')
    ->willReturn([
        'USERNAME' => 'testuser',
        'SERVER' => 'testserver'
    ]);

$mock = $settings->getSettings();

So far so good, but when I try to pass that mocked object to authenticate it throws an error:

$this->assertEquals($testvalue, Utilities::authenticate($settings));
Argument 1 passed to Utilities::authenticate() must be an instance of Settings, instance of Mock_Settings_d0361624 given

How can I mock the Settings object so it appears to be a "real" object to the Utilities class?

EDIT to add the getSettings function:

class Settings {

private $settings;
private static $instance;

public function __construct(){
    $configfile = "config/config.ini";
    //if( !$this->settings = parse_ini_file( $configfile, true ) ){
        //die('SETTINGS OBJECT NOT FOUND OR COULD NOT BE PARSEd');
    //}
}
/**
 * @return Settings
 */
public static function getSettings(){
    if ( !self::$instance ){
        self::$instance = new Settings();
    }
    if(!utilities::authenticate(self::$instance)) die('AUTHENTICATION FAILED-- CHECK API KEY');
    return self::$instance;
}

Upvotes: 2

Views: 789

Answers (1)

Matteo
Matteo

Reputation: 39370

This error message occur when you create the object with a wrong classname. Check the getMock method pass the full classname with the namespace, like:

$settings = $this->getMock('Acme\DemoBundle\Model\Settings', array('getSettings'));

Hope this help

EDIT

The method is static and the phpunit library don't support mock static method as described here and here.

So you can use some mockking framework such as Phake that support mocking static method as described here. As working example:

public function test_authenticate()
{
    $settings = \Phake::mock('Acme\DemoBundle\Model\Settings');

    \Phake::whenStatic($settings)
        ->getSettings()
        ->thenReturn([
            'USERNAME' => 'testuser',
            'SERVER' => 'testserver'
        ]);

    $mock = $settings->getSettings();

    $testvalue = true;
    $this->assertEquals($testvalue, Utilities::authenticate($settings));
}

Upvotes: 2

Related Questions