php - 我应该如何创建一个总是超时的测试资源

标签 php python apache url timeout

我正在单元测试一个 URL getter ,我需要一个总是导致 urllib2.urlopen() (Python) 超时的测试 url。我试过制作一个只有 sleep(10000) 的 php 页面,但这会导致 500 内部服务器错误。

我如何制作一个资源,无论何时请求它都会导致客户端连接超时?

最佳答案

Edit: I saw the [php] tag and just assumed this was PHP code -- however, the same principles can apply in Python if that's the language you're working with.

成功的单元测试要求您测试代码单元完全隔离所有外部影响。这意味着,如果您的测试依赖于文件系统(或在本例中为某些外部 Web 服务器)之类的东西才能正常运行,那么您就错了。当您的测试依赖于外部网络服务器时,您会显着增加测试代码的复杂性,并引入误报和其他错误测试结果的可能性。

听起来当前的测试实现需要一个成熟的模拟网络服务器来提供特定的、可测试的响应。 不应该是这种情况。这种影响深远的测试依赖性只会导致上述问题。

更好的方法

但是您如何测试 native PHP 功能及其与远程数据(如 HTTP 或 FTP)的交互?答案是将测试 “接缝” 添加到您的代码中。考虑以下简单示例:

<?php

class UrlRetriever {

    public function retrieve($uri) {
        $response = $this->doRetrieve($uri);
        if (false !== $response) {
            return $response;
        } else {
            throw new RuntimeException(
                'Retrieval failed for ' . $uri
            );
        }
    }

    /**
     * A test seam to allow mocking of `file_get_contents` results
     */
    protected function doRetrieve($uri) {
        // suppress the warning from a failure since we're testing against the
        // return value (FALSE on failure)
        return @file_get_contents($uri); 
    }
}

你的相关 PHPUnit 测试看起来像这样:

<?php

class UrlRetrieverTest extends PHPUnit_Framework_TestCase {

    /**
     * @covers UrlRetriever::retrieve
     * @expectedException RuntimeException
     */
    public function testRetrieveThrowsExceptionOnFailure() {
        $retriever = $this->getMock('UrlRetriever', array('doRetrieve'));
        $retriever->expects($this->once())
                  ->method('doRetrieve')
                  ->will($this->returnValue(false));

        $retriever->retrieve('http://someurl');
    }

    /**
     * @covers UrlRetriever::retrieve
     */
    public function testSomeSpecificOutputIsHandledCorrectly() {
        $expectedValue = 'Some value I want to manipulate';

        $retriever = $this->getMock('UrlRetriever', array('doRetrieve'));
        $retriever->expects($this->once())
                  ->method('doRetrieve')
                  ->will($this->returnValue($expectedValue));

        $response = $retriever->retrieve('http://someurl');
        $this->assertEquals($response, $expectedValue);
    }
}

显然,这个示例是人为设计的并且非常简单,但是这个概念可以根据需要扩展。通过创建类似上述 UrlRetriever::doRetrieve 方法的测试接缝,我们能够使用标准测试框架轻松模拟结果。

这种方法使我们能够测试操作远程资源的 native PHP 函数的其他复杂结果,而无需接触外部 Web 服务器或引入被测系统外部错误的可能性。

在 OP 的特定情况下,如果需要超时结果,只需模拟相关的测试接缝方法以执行 native PHP 函数在超时时执行的操作。

关于php - 我应该如何创建一个总是超时的测试资源,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12753527/

相关文章:

python - matplotlib 中的轴刻度标签填充

python - 如何在Python中获取发布文件的路径

java - 集成总线添加外部 jar 异常

php - 交响乐 4 : doctrine in command

java - 无法将模拟器与本地主机连接?安卓 |火力基地

php - 正则表达式匹配第一个单词与最后一个单词相同

python - 基于列 Pandas 值的不同聚合函数

php - 在 Ubuntu 14.04 x64 DigitalOcean 上安装带有主题的特定 Wordpress 安装

php - Apache 的 mod_php 还是 FastCGI?哪个对 Wordpress 有好处?

PHP和MySql登录出现错误