Faisal Irfan
Faisal Irfan

Reputation: 11

PHPUnit Symfony Test Case error

I am new to Symfony, I have wrote small app now have to add unit tests, here is my controller:

<?php
namespace myBundle\Controller;

use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\RedirectResponse;

class IndexController extends AbstractController
{

    /**
     * @param \Symfony\Component\HttpFoundation\Request $request
     * @return \Symfony\Component\HttpFoundation\Response
     */
    public function indexAction(Request $request)
    {

        if ($this->getRequest()->isMethod('POST')) {
            // Do Something
        }

        // Do Something otherwise
    }
}

My test:

class IndexControllerTest extends \PHPUnit_Framework_TestCase
{
    protected $testController;

    public function setUp()
    {

        $this->testController =
            $this->getMockBuilder('myBundle\Controller\IndexController')
                ->disableOriginalConstructor()
                ->getMock();

    }

    public function testPostSaveActionWithBadRequest()
    {
        $expectation = 'Some text ';

        $response = $this->testController->indexAction(new Request);
        $this->assertInstanceOf(
            'Symfony\Component\HttpFoundation\JsonResponse',
            $response
        );
        $content = json_decode($response->getContent());
        $this->assertEquals($expectation, $content->error);
    }

}

When I run this test I get following:

PHP Fatal error: Call to a member function get()

which is basically on following line

if ($this->getRequest()->isMethod('POST')) {

this tells me the container is null (I verified it by printing dump of the container).

any idea what am I missing here or is there a way to provide container as dependency for that test.

I really appreciate all the help.

thanks FI

Upvotes: 1

Views: 1496

Answers (1)

Jakub Zalas
Jakub Zalas

Reputation: 36191

You're trying to mock the class you're suppose to test:

$this->testController =
    $this->getMockBuilder('myBundle\Controller\IndexController')
        ->disableOriginalConstructor()
        ->getMock();

You should actually instantiate the class you're testing, and mock or stub its collaborators.

However, in this particular scenario, instead of writing a unit test, write a functional test. There's a chapter on writing functional tests in Symfony docs that'll help you.

Your controller uses lots of framework classes (classes that don't belong to you), and you shouldn't mock them either. That's why functional tests are better in this case. Also, make sure you move as much code as possible out of your controller, so you can properly unit test that part (and write as little functional tests as possible).

In the meantime read some books on unit testing (in the following order):

Upvotes: 4

Related Questions