如何使用返回 IP 的函数进行 PHPUnit 测试?

Posted

技术标签:

【中文标题】如何使用返回 IP 的函数进行 PHPUnit 测试?【英文标题】:How to get PHPUnit testing working with a function that returns an IP? 【发布时间】:2021-08-23 07:14:41 【问题描述】:

我刚接触 TDD,我已经用 phpStorm 安装了 PHPUnit。

我有这个类和函数,我想测试IP地址匹配。

class ip_request


    function getRealIpAddr()
    
        if (!empty($_SERVER['HTTP_CLIENT_IP']))   //check ip from share internet
        
            $ip=$_SERVER['HTTP_CLIENT_IP'];
        
        elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
        
            $ip=$_SERVER['HTTP_X_FORWARDED_FOR'];
        
        else
        
            $ip=$_SERVER['REMOTE_ADDR'];
        
        return $ip;
    

我正在尝试为测试创建代码,但我不确定要输入什么。

我试过了

public function testGetRealIpAddr()
    
        
        $expected = '127.0.0.1';
        $this->assertEquals($expected, $test);
    

但是$test 显然是未定义的。

接下来我该怎么做?

给出的尝试建议

public function testGetRealIpAddr()
    
        $UserIpAddress = $this
            ->getMockBuilder('ip_request')
            ->getMock();

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

但我现在得到的错误是

Trying to configure method "getRealIpAddr()" which cannot be configured because it does not exist, has not been specified, is final, or is static

【问题讨论】:

这能回答你的问题吗? How to use server variables in PHPUnit Test cases? 【参考方案1】:

你要测试的方法/函数有一个隐藏的依赖$_SERVER.

发现这一点还可以导致解决方案使代码更加模块化和更容易测试。

这通过使用可选参数公开先前隐藏的依赖项来工作:

function getRealIpAddr(array $server = null)

    $server ??= $_SERVER;
    
    if (!empty($server['HTTP_CLIENT_IP']))   //check ip from share internet
    
        $ip = $server['HTTP_CLIENT_IP'];
     elseif (!empty($server['HTTP_X_FORWARDED_FOR']))   //to check ip is pass from proxy
    
        $ip = $server['HTTP_X_FORWARDED_FOR'];
     else 
        $ip = $server['REMOTE_ADDR'];
    

    return $ip;

在单元测试中,您然后根据输入测试函数结果。

但是单元测试并不能突出该函数存在的大量安全问题,这可能超出了您的问题的范围,所以我只发表评论。

【讨论】:

谢谢我确实解决了这个问题,但我很感激你向我展示了这个方法,谢谢。【参考方案2】:

我以类似于@hakre 建议的方式解决了这个问题,

$ip = $_SERVER['REMOTE_ADDR'] ?? '127.0.0.1';

我在该语句的末尾添加了?? '127.0.0.1',并且修复了它。

还刚刚更新了我的测试功能以仅显示

 $local = new ip_request();
 $this->assertEquals('127.0.0.1', $local->getRealIpAddr());

【讨论】:

以上是关于如何使用返回 IP 的函数进行 PHPUnit 测试?的主要内容,如果未能解决你的问题,请参考以下文章

使用 PHPUnit 对具有多种用户类型的网站进行单元测试的最佳方法

PHPUnit 如何获得模拟方法的真实返回值?

如何在 laravel 5.5 中使用 phpunit 测试中间件?

如果该函数应该杀死 PHP,您如何使用 PHPUnit 来测试该函数?

PHPUnit中的测试方法应该如何命名

PHPUnit - 使用 $_POST 变量测试 MVC 控制器