donatj / mock-webserver
简单的模拟Web服务器,用于单元测试
v2.7.2
2024-01-22 20:41 UTC
Requires
- php: >=7.1
- ext-json: *
- ext-sockets: *
- ralouphie/getallheaders: ~2.0 || ~3.0
Requires (Dev)
- ext-curl: *
- corpus/coding-standard: ^0.6.0 || ^0.8.0
- donatj/drop: ^1.0
- friendsofphp/php-cs-fixer: ^3.1
- phpunit/phpunit: ~7|~9
- squizlabs/php_codesniffer: ^3.6
- dev-master
- v2.7.2
- v2.7.1
- v2.7.0
- v2.6.3
- v2.6.2
- v2.6.1
- v2.6.0
- v2.5.0
- v2.4.1
- v2.4.0
- v2.3.0
- v2.2.0
- v2.1.1
- v2.1.0
- v2.0.0
- v1.0.0
- v1.0.0-beta.3
- v1.0.0-beta.2
- v1.0.0-beta
- v0.5.0
- v0.4.1
- v0.4.0
- v0.2.0
- v0.1.0
- dev-feature/phpstan
- dev-test/DelayedResponse
- dev-revert-42-v3wip
- dev-jonasraoni-v3wip
- dev-reduce-sleep
- dev-refactor/Testability
This package is auto-updated.
Last update: 2024-09-13 16:27:36 UTC
README
简单的、易于使用的模拟Web服务器,用于PHP单元测试。与PHPUnit和其他单元测试框架简单兼容。
单元测试HTTP请求可能很困难,尤其是在难以注入请求库或不是最佳选择的情况下。这有助于大大简化过程。
模拟Web服务器创建一个本地Web服务器,你可以针对它进行预定义的请求。
文档
要求
- php: >=7.1
- ext-sockets: *
- ext-json: *
- ralouphie/getallheaders: ~2.0 || ~3.0
安装
使用以下命令安装最新版本
composer require --dev 'donatj/mock-webserver'
示例
基本用法
以下示例显示了最基本的用法。如果你没有定义路径,服务器将简单地回弹一个描述请求的JSON体。
<?php use donatj\MockWebServer\MockWebServer; require __DIR__ . '/../vendor/autoload.php'; $server = new MockWebServer; $server->start(); $url = $server->getServerRoot() . '/endpoint?get=foobar'; echo "Requesting: $url\n\n"; echo file_get_contents($url);
输出
Requesting: http://127.0.0.1:61874/endpoint?get=foobar
{
"_GET": {
"get": "foobar"
},
"_POST": [],
"_FILES": [],
"_COOKIE": [],
"HEADERS": {
"Host": "127.0.0.1:61874",
"Connection": "close"
},
"METHOD": "GET",
"INPUT": "",
"PARSED_INPUT": [],
"REQUEST_URI": "\/endpoint?get=foobar",
"PARSED_REQUEST_URI": {
"path": "\/endpoint",
"query": "get=foobar"
}
}
简单
<?php use donatj\MockWebServer\MockWebServer; use donatj\MockWebServer\Response; require __DIR__ . '/../vendor/autoload.php'; $server = new MockWebServer; $server->start(); // We define the server's response to requests of the /definedPath endpoint $url = $server->setResponseOfPath( '/definedPath', new Response( 'This is our http body response', [ 'Cache-Control' => 'no-cache' ], 200 ) ); echo "Requesting: $url\n\n"; $content = file_get_contents($url); // $http_response_header is a little known variable magically defined // in the current scope by file_get_contents with the response headers echo implode("\n", $http_response_header) . "\n\n"; echo $content . "\n";
输出
Requesting: http://127.0.0.1:61874/definedPath
HTTP/1.1 200 OK
Host: 127.0.0.1:61874
Date: Tue, 31 Aug 2021 19:50:15 GMT
Connection: close
X-Powered-By: PHP/7.3.25
Cache-Control: no-cache
Content-type: text/html; charset=UTF-8
This is our http body response
更改默认响应
<?php use donatj\MockWebServer\MockWebServer; use donatj\MockWebServer\Responses\NotFoundResponse; require __DIR__ . '/../vendor/autoload.php'; $server = new MockWebServer; $server->start(); // The default response is donatj\MockWebServer\Responses\DefaultResponse // which returns an HTTP 200 and a descriptive JSON payload. // // Change the default response to donatj\MockWebServer\Responses\NotFoundResponse // to get a standard 404. // // Any other response may be specified as default as well. $server->setDefaultResponse(new NotFoundResponse); $content = file_get_contents($server->getServerRoot() . '/PageDoesNotExist', false, stream_context_create([ 'http' => [ 'ignore_errors' => true ], // allow reading 404s ])); // $http_response_header is a little known variable magically defined // in the current scope by file_get_contents with the response headers echo implode("\n", $http_response_header) . "\n\n"; echo $content . "\n";
输出
HTTP/1.1 404 Not Found
Host: 127.0.0.1:61874
Date: Tue, 31 Aug 2021 19:50:15 GMT
Connection: close
X-Powered-By: PHP/7.3.25
Content-type: text/html; charset=UTF-8
VND.DonatStudios.MockWebServer: Resource '/PageDoesNotExist' not found!
PHPUnit
<?php use donatj\MockWebServer\MockWebServer; use donatj\MockWebServer\Response; class ExampleTest extends PHPUnit\Framework\TestCase { /** @var MockWebServer */ protected static $server; public static function setUpBeforeClass() : void { self::$server = new MockWebServer; self::$server->start(); } public function testGetParams() : void { $result = file_get_contents(self::$server->getServerRoot() . '/autoEndpoint?foo=bar'); $decoded = json_decode($result, true); $this->assertSame('bar', $decoded['_GET']['foo']); } public function testGetSetPath() : void { // $url = http://127.0.0.1:61874/definedEndPoint $url = self::$server->setResponseOfPath('/definedEndPoint', new Response('foo bar content')); $result = file_get_contents($url); $this->assertSame('foo bar content', $result); } public static function tearDownAfterClass() : void { // stopping the web server during tear down allows us to reuse the port for later tests self::$server->stop(); } }
延迟响应的使用
默认情况下,响应将立即发生。如果你想要测试超时,DelayedResponse响应包装器可能很有用。
<?php use donatj\MockWebServer\DelayedResponse; use donatj\MockWebServer\MockWebServer; use donatj\MockWebServer\Response; require __DIR__ . '/../vendor/autoload.php'; $server = new MockWebServer; $server->start(); $response = new Response( 'This is our http body response', [ 'Cache-Control' => 'no-cache' ], 200 ); // Wrap the response in a DelayedResponse object, which will delay the response $delayedResponse = new DelayedResponse( $response, 100000 // sets a delay of 100000 microseconds (.1 seconds) before returning the response ); $realtimeUrl = $server->setResponseOfPath('/realtime', $response); $delayedUrl = $server->setResponseOfPath('/delayed', $delayedResponse); echo "Requesting: $realtimeUrl\n\n"; // This request will run as quickly as possible $start = microtime(true); file_get_contents($realtimeUrl); echo "Realtime Request took: " . (microtime(true) - $start) . " seconds\n\n"; echo "Requesting: $delayedUrl\n\n"; // The request will take the delayed time + the time it takes to make and transfer the request $start = microtime(true); file_get_contents($delayedUrl); echo "Delayed Request took: " . (microtime(true) - $start) . " seconds\n\n";
输出
Requesting: http://127.0.0.1:61874/realtime
Realtime Request took: 0.015669107437134 seconds
Requesting: http://127.0.0.1:61874/delayed
Delayed Request took: 0.10729098320007 seconds
同一端点的多个响应
响应堆栈
如果你需要一个有序的响应集,可以使用ResponseStack。
<?php use donatj\MockWebServer\MockWebServer; use donatj\MockWebServer\Response; use donatj\MockWebServer\ResponseStack; require __DIR__ . '/../vendor/autoload.php'; $server = new MockWebServer; $server->start(); // We define the servers response to requests of the /definedPath endpoint $url = $server->setResponseOfPath( '/definedPath', new ResponseStack( new Response("Response One"), new Response("Response Two") ) ); echo "Requesting: $url\n\n"; $contentOne = file_get_contents($url); $contentTwo = file_get_contents($url); // This third request is expected to 404 which will error if errors are not ignored $contentThree = file_get_contents($url, false, stream_context_create([ 'http' => [ 'ignore_errors' => true ] ])); // $http_response_header is a little known variable magically defined // in the current scope by file_get_contents with the response headers echo $contentOne . "\n"; echo $contentTwo . "\n"; echo $contentThree . "\n";
输出
Requesting: http://127.0.0.1:61874/definedPath
Response One
Response Two
Past the end of the ResponseStack
按方法响应
如果你需要通过方法改变单个端点的响应,可以使用ResponseByMethod响应对象。
<?php use donatj\MockWebServer\MockWebServer; use donatj\MockWebServer\Response; use donatj\MockWebServer\ResponseByMethod; require __DIR__ . '/../vendor/autoload.php'; $server = new MockWebServer; $server->start(); // Create a response for both a POST and GET request to the same URL $response = new ResponseByMethod([ ResponseByMethod::METHOD_GET => new Response("This is our http GET response"), ResponseByMethod::METHOD_POST => new Response("This is our http POST response", [], 201), ]); $url = $server->setResponseOfPath('/foo/bar', $response); foreach( [ ResponseByMethod::METHOD_GET, ResponseByMethod::METHOD_POST ] as $method ) { echo "$method request to $url:\n"; $context = stream_context_create([ 'http' => [ 'method' => $method ] ]); $content = file_get_contents($url, false, $context); echo $content . "\n\n"; }
输出
GET request to http://127.0.0.1:61874/foo/bar:
This is our http GET response
POST request to http://127.0.0.1:61874/foo/bar:
This is our http POST response