Elastica
Elastica copied to clipboard
How to mock elasticsearch responses for unit tests
Problem
I want to get unit test coverage for my own logic that invokes Elastica. How do I mock responses from Elastica to test specific outcomes?
One potential solution
Make a mock transport based on this package's Elastica\Transport\Guzzle
transport, and take advantage of the Guzzle handler to mock responses.
MockTransport.php
<?php
namespace App\Tests;
use Elastica\Connection;
use Elastica\Transport\Guzzle;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
class MockTransport extends Guzzle
{
/**
* @var MockHandler
*/
protected static $mockHandler;
/**
* @return MockHandler
*/
public static function getMockHandler(): MockHandler
{
if (!static::$mockHandler) {
static::$mockHandler = new MockHandler();
}
return static::$mockHandler;
}
/**
* {@inheritDoc}
*/
protected function _getGuzzleClient($baseUrl, $persistent = true)
{
return new Client([
'base_uri' => $baseUrl,
'handler' => static::getMockHandler(),
]);
}
}
Then you can use the mock transport when you set up your client e.g
$client = new \Elastica\Client(['transport' => MockTransport::class]);
MockTransport::getMockHandler()->append(function () {
return new \GuzzleHttp\Psr7\Response\Response(
... // Add your mock Elasticsearch response payload
);
});
$response = $client->request(...); // Add your arguments
// Make your assertions here...
I have an Injector in my project, so was able to use the injector to assign the MockHandler (during unit tests) to logic that instantiates an Elastica\Client
. You may need your own approach to assign the mock handler during unit test execution.
@jakxnz I must confess, this is not something I was thinking about before. Do you need anything from us or does the above work for you?
@ruflin, thanks for engaging in this! This suits our needs, but I am open to more effective solutions if anyone knows them
@jakxnz : is your logic being part of ES requests? Like a new query type or endpoint? If not, you could mock the ES response, instead of going down to mocking guzzle requests. (my 2 cents)
No @thePanz , my logic uses all out-of-the-box types/endpoints. Mocking the ES response sounds like it could be quite clean, do you have an example of how you would do that?