Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use server variables in PHPUnit Test cases?

I am testing modules using PHPUnit Test cases. All the things working fine but when i use $_SERVER['REMOTE_ADDR'] it gives fatal error and stops execution.

CategoryControllerTest.php

<?php
namespace ProductBundle\Controller\Tests\Controller;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class CategoryControllerTest extends WebTestCase {

     protected function setUp() {
        static::$kernel = static::createKernel();
        static::$kernel->boot();
        $this->container = static::$kernel->getContainer();
        $this->em = static::$kernel->getContainer()->get('doctrine')->getManager();
    }

    public function testCategory() {
        $ip_address = $_SERVER['REMOTE_ADDR'];
        $client = static::createClient(
          array(), array('HTTP_HOST' => static::$kernel->getContainer()->getParameter('test_http_host')
        ));

        $crawler = $client->request('POST', '/category/new');
        $client->enableProfiler();

        $this->assertEquals('ProductBundle\Controller\CategoryController::addAction', $client->getRequest()->attributes->get('_controller'));
        $form = $crawler->selectButton('new_category')->form();
        $form['category[name]'] = "Electronics";
        $form['category[id]']   = "For US";
        $form['category[ip]']   = $ip_address;
        $client->submit($form);

        $this->assertTrue($client->getResponse()->isRedirect('/category/new')); // check if redirecting properly
        $client->followRedirect();
        $this->assertEquals(1, $crawler->filter('html:contains("Category Created Successfully.")')->count());
    }
}

Error

There was 1 error:

1) ProductBundle\Tests\Controller\CategoryControllerTest::testCategory Undefined index: REMOTE_ADDR

I have tried to add it in setUp() function but it's not working as well.

like image 927
Janvi Avatar asked Jan 11 '17 10:01

Janvi


People also ask

Which method is used to create a mock with PHPUnit?

PHPUnit provides methods that are used to automatically create objects that will replace the original object in our test. createMock($type) and getMockBuilder($type) methods are used to create mock object. The createMock method immediately returns a mock object of the specified type.

What is assertion in PHPUnit?

The assertEquals() function is a builtin function in PHPUnit and is used to assert whether the actual obtained value is equals to expected value or not. This assertion will return true in the case if the expected value is the same as the actual value else returns false.

What are PHPUnit fixtures?

One of the most time-consuming parts of writing tests is writing the code to set the world up in a known state and then return it to its original state when the test is complete. This known state is called the fixture of the test.


2 Answers

Technically, you haven't sent a request to your application yet, so there is no remote address to refer to. That in fact is what your error is telling us too.

To work around this:

  1. move the line to be below:

    // Won't work, see comment below    
    $crawler = $client->request('POST', '/category/new');
    
  2. Or you could make up an IP address and test with that. Since you're only using the IP to save a model, that will work just as well.

Like @apokryfos mentioned in the comments, it's considered bad practice to access superglobals in test cases. So option 2 is probably your best choice here.

like image 59
Loek Avatar answered Oct 21 '22 13:10

Loek


Create service which returns ip address and mock the service in test case.

Here, create controller and service as UserIpAddress. get() will return ip address of user.

service.yml

UserIpAddress:
    class: AppBundle\Controller\UserIpAddressController
    arguments: 
    container: "@service_container"  

UserIpAddressController.php

class UserIpAddressController
{
  public function get()
  {
    return $_SERVER['REMOTE_ADDR'];
  }
}

Create mock of "UserIpAddress" service. It will override existing service. Use 'UserIpAddress' service to get ip address in your project.

CategoryControllerTest.php

$UserIpAddress = $this->getMockBuilder('UserIpAddress')
    ->disableOriginalConstructor()
    ->getMock();

$UserIpAddress->expects($this->once())
  ->method('get')
  ->willReturn('192.161.1.1'); // Set ip address whatever you want to use

Now, get ip address using $UserIpAddress->get();

like image 45
Gopal Joshi Avatar answered Oct 21 '22 12:10

Gopal Joshi