I need to test my controller action and i need advice. It's how my controller looks:
class SampleController extends Controller
{
public function sampleAction(Request $request)
{
$lang = 'en';
return $this->render('movie.html.twig', [
'icons' => $this->container->getParameter('icons'),
'language' => $lang,
'extraServiceUrl' => $this->getAccount()->getExtraServiceUrl(),
'websiteUrl' => $this->getAccount()->getWebsiteUrl(),
'myProfileUrl' => $this->getAccount()->getMyProfileUrl(),
'redirectForAnonUser' => $this->container->get('router')->generate('login'),
'containerId' => $request->getSession()->get("_website"),
'isRestricted' => $this->getLicense()->isRestricted(),
'isPremiumAvaible' => $this->getLicense()->isPremiumAvaible()
]);
}
private function getAccount()
{
return $this->container->get('context')->getAccount();
}
private function getLicense()
{
return $this->container->get('license');
}
}
And now, normally I test controllers by behat, but this one just render twig and set variables in so I probably can't test it by behat. I tried to test it by phpUnit and it can work, but what is the best way to mock chain methods? Or maybe you have other way to test it? btw container is private so I need reflection? Greetings
PHPUnit is a unit testing framework for the PHP programming language. It is an instance of the xUnit architecture for unit testing frameworks that originated with SUnit and became popular with JUnit. PHPUnit was created by Sebastian Bergmann and its development is hosted on GitHub.
Likewise, PHPUnit mock object is a simulated object that performs the behavior of a part of the application that is required in the unit test. The developers control the mock object by defining the pre-computed results on the actions.
PHPUnit assertTrue() Function The assertTrue() function is a builtin function in PHPUnit and is used to assert whether the assert value is true or not. This assertion will return true in the case if the assert value is true else returns false. In case of true the asserted test case got passed else test case got failed.
There are 2 approaches to test Controllers:
Unit tests are good in testing services with just few dependencies. But for controllers Functional tests are better in most cases.
Functional test with session mocking in you case could look like:
namespace Tests\AppBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PostControllerTest extends WebTestCase
{
public function testYourAction()
{
$client = static::createClient();
$user = null;//todo: load user for test from DB here
/** @var Session $session */
$session = $client->getContainer()->get('session');
$firewall = 'main';
$token = new UsernamePasswordToken($user, null, $firewall, $user->getRoles());
$session->set('_security_'.$firewall, serialize($token));
$session->save();
$cookie = new Cookie($session->getName(), $session->getId());
$this->client->getCookieJar()->set($cookie);
$crawler = $client->request('GET', '/your_url');
$response = $this->client->getResponse();
$this->assertEquals(200, $response->getStatusCode());
//todo: do other assertions. For example, check that some string is present in response, etc..
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With