Reputation: 125
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.
Upvotes: 6
Views: 8659
Reputation: 11
You can either create another class that will return the server var then mock it.
Or you can set/unset the server var directly into your test case. Did it with PHPUnit 6.2.2 :
/**
* Return true if the user agent matches a robot agent
*/
public function testShouldReturnTrueIfRobot()
{
$_SERVER['HTTP_USER_AGENT'] = 'Mozilla/5.0 (compatible; Googlebot/2.1; +http://www.google.com/bot.html)';
$this->configMock->method('getRobotUserAgents')
->willReturn('bot|crawl|slurp|spider|mediapartner');
$test = $this->robotTest->isBot();
static::assertTrue($test);
}
/**
* Test return false if no user agent
*/
public function testShouldReturnFalseIfNoAgentUser()
{
unset($_SERVER['HTTP_USER_AGENT']);
$test = $this->robotTest->isBot();
static::assertFalse($test);
}
Where tested method is :
/**
* Detect if current user agent matches a robot user agent
*
* @return bool
*/
public function isBot(): bool
{
if (empty($_SERVER['HTTP_USER_AGENT'])) {
return false;
}
$userAgents = $this->config->getRobotUserAgents();
$pattern = '/' . $userAgents . '/i';
return \preg_match($pattern, $_SERVER['HTTP_USER_AGENT']);
}
Upvotes: 1
Reputation: 2358
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();
Upvotes: 0
Reputation: 4135
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:
move the line to be below:
// Won't work, see comment below
$crawler = $client->request('POST', '/category/new');
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.
Upvotes: 1