Skip to content

Instantly share code, notes, and snippets.

@olleharstedt
Created August 21, 2020 18:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save olleharstedt/2db50149948eb790082f8651344e8b0b to your computer and use it in GitHub Desktop.
Save olleharstedt/2db50149948eb790082f8651344e8b0b to your computer and use it in GitHub Desktop.
Amphp and mocking
<?php
require __DIR__ . '/../vendor/autoload.php';
use Amp\Http\Client\HttpClientBuilder;
use Amp\Http\Client\Request;
use Amp\Loop;
use Amp\ByteStream\ClosedException;
use Amp\File;
interface IO extends Amp\Promise
{
// IO must be comparable to be able to test it
public function equals(IO $io);
}
class WriteIO implements IO
{
private $message;
private $handle;
public function __construct($handle, $message)
{
$this->message = $message;
$this->handle = $handle;
}
public function onResolve($onResolved)
{
$this->handle->write($this->message)->onResolve($onResolved);
}
public function equals(IO $io)
{
return $io->message === $this->message;
}
}
class FileSaver
{
private $logger;
private $httpClient;
public function __construct($logger, $httpClient)
{
$this->logger = $logger;
$this->httpClient = $httpClient;
}
public function saveFile($path, $file)
{
$logger = $this->logger;
yield new WriteIO($logger, 'Saving file ' . $path);
$request = new Request('https://cloudfiles.fooservice.com/', 'POST');
$request->setBody($file);
$response = yield $this->httpClient->request($request);
if ($response->getStatus() === 200) {
yield new WriteIO($logger, 'Successfully saved file ' . $path);
} else {
$msg = 'Failed to save file ' . $path;
yield new WriteIO($logger, $msg);
throw new Exception($msg);
}
}
}
Loop::run(function() {
$httpClient = HttpClientBuilder::buildDefault();
$logger = yield File\open('log.txt', "c+");
$fileSaver = new FileSaver($logger, $httpClient);
// Comment out live run.
//yield from $fileSaver->saveFile('moo', 0);
//return;
// List of effects expected by saveFile()
$effects = [
[
'yield' => new WriteIO(null, 'Saving file moo'),
'send' => null
],
[
'yield' => null,
'send' => new class { public function getStatus() { return 200; } }
]
];
$gen = $fileSaver->saveFile('moo', 0);
testGenerator($gen, $effects);
});
function testGenerator($gen, $effects)
{
// Loop all effects and make sure they correspond to expectations.
foreach ($gen as $i => $promise) {
if ($effects[$i]['yield']) {
if (!$promise->equals($effects[$i]['yield'])) {
throw new Exception('Failed test');
}
}
if ($effects[$i]['send']) {
$gen->send($effects[$i]['send']);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment