0

I want to test a controller using a mock.

In my controller

public function myAction() {
    $email = new MandrillApi(['template_name'=>'myTemplate']);
    $result = $email
        ->subject('My title')
        ->from('no-reply@test.com')
        ->to('dest@test.com')
        ->send();

    if ( isset($result[0]['status']) && $result[0]['status'] === 'sent' )
        return $this->redirect(['action' => 'confirmForgotPassword']);

    $this->Flash->error(__("Error"));
}

In test

public function testMyAction() {
        $this->get("users/my-action");
        $this->assertRedirect(['controller' => 'Users', 'action' => 'confirmForgotPassword']);
    }

How do I mock the class MandrillApi ? thank you

Ozee
  • 146
  • 1
  • 7
  • I'd first evaluate whether you actually need to mock the class at all. I guess you don't want to send the data to the live API in your tests? Given that you don't pass any credentials, I'd assume that the class reads some global configuration values? Maybe it's possible to configure it so that it sends the data to a dummy endpoint? – ndm Mar 25 '16 at 15:06
  • Yes it's possible de pass a test key for this api but I would like to know if it was possible to mock a class in a controller – Ozee Mar 29 '16 at 07:10

1 Answers1

2

In your controller-test:

public function controllerSpy($event){
    parent::controllerSpy($event);
    if (isset($this->_controller)) {
        $MandrillApi = $this->getMock('App\Pathtotheclass\MandrillApi', array('subject', 'from', 'to', 'send'));
        $this->_controller->MandrillApi = $MandrillApi;
        $result = [
            0 => [
                'status' => 'sent'
            ]
        ];
        $this->_controller->MandrillApi
            ->method('send')
            ->will($this->returnValue($result));
    }
}

The controllerSpy method will insert the mocked object once the controller is setup correctly. You don't have to call the controllerSpy method, it gets executed automatically at some point after you make the $this->get(... call in your test.

Obviously you have to change the App\Pathtotheclass-part of the mock-generation to fit the location of your MandrillApi-class.

David Albrecht
  • 634
  • 1
  • 4
  • 15