Situation: I am testing a Zend controller action, where a user has to login or otherwise will get redirected:
<?php
namespace MyModule\Controller;
use Zend\Mvc\Controller\AbstractActionController;
use Zend\View\Model\ViewModel;
class GameController extends AbstractActionController
{
public function indexAction()
{
if ($this->zfcUserAuthentication()->hasIdentity()) {
$view = new ViewModel();
$user = $this->zfcUserAuthentication()->getIdentity();
$view->username = $user->getUsername();
return $view;
} else {
$this->redirect()->toRoute("mymodule/overview");
}
}
}
My test case then looks like this:
<?php
namespace MyModuleTest\Controller;
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase;
use ZfcUser\Controller\Plugin\ZfcUserAuthentication;
use ZfcUser\Entity\User;
class GameControllerTest extends AbstractHttpControllerTestCase
{
public function setUp()
{
$this->setApplicationConfig(include __DIR__ . '/../../../../../config/application.config.php');
parent::setUp();
}
public function testIndexAction()
{
// Mock the authentication user
$user = $this->createMock(User::class);
$user->expects($this->any())->method('getId')->will($this->returnValue('1'));
// Mock the authentication adapter
$authentication = $this->createMock(ZfcUserAuthentication::class);
$authentication->expects($this->any())->method('hasIdentity')->will($this->returnValue(true));
$authentication->expects($this->any())->method('getIdentity')->will($this->returnValue($user));
$this->dispatch('/mymodule/game');
$this->assertResponseStatusCode(302);
$this->assertModuleName('MyModule');
$this->assertMatchedRouteName('mymodule/game');
$this->assertControllerName('MyModule\Controller\Game');
$this->assertControllerClass('GameController');
$this->assertActionName('index');
// TODO: Log in the user
// How do I install the mocked Zfc authentication?
$this->dispatch('/mymodule/game');
$this->assertResponseStatusCode(200);
$this->assertModuleName('MyModule');
$this->assertMatchedRouteName('mymodule/game');
$this->assertControllerName('MyModule\Controller\Game');
$this->assertControllerClass('GameController');
$this->assertActionName('index');
}
}
Problem: There are a few StackOverflow posts how to mock the ZfcUser authentication service, but how can I do this dynamically (Working code example)? First, I want to trigger the redirect (and check for the 302 HTTP code), then I want to login the user (mock it) and check it again (and receive a 200 HTTP code)
You should mock the
ZfcUserservice in your tests. Testing the working ofZfcUserfalls outside the scope of your application and is done in the tests for theZfcUsermodule. For example here for 302 errors:ZfcUser/tests/ZfcUserTest/Controller/RedirectCallbackTest.php ZfcUser/src/ZfcUser/Controller/RedirectCallback.php ZfcUser/tests/ZfcUserTest/Controller/UserControllerTest.php
UPDATE:
So your
$this->zfcUserAuthentication()method should return the mocked class that you prepared. This part of your code is not in the question, so I cannot give you more details on this. Best would be to have theZfcUserauthentication service injected through constructor dependency injection (as a dependency in your class constructor).