Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Test controller action by phpunit, symfony

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

like image 278
jager91 Avatar asked Nov 15 '17 13:11

jager91


People also ask

What is PHPUnit testing?

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.

What is mock PHPUnit?

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.

What is assertion in PHPUnit?

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.


Video Answer


1 Answers

There are 2 approaches to test Controllers:

  1. Functional tests. You test whole application together - from fetching data from db to rendering response in Symfony core. You can use fixtures to set-up test data.
  2. Unit test. You test only this method, all dependencies are mocked.

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..
    }
}
like image 54
Maksym Moskvychev Avatar answered Oct 09 '22 05:10

Maksym Moskvychev