Skip to content

meare/juggler

Repository files navigation

Juggler

Latest Version on Packagist Software License Build Status Code Coverage Scrutinizer Code Quality

Juggler is a PHP client for mountebank - open source tool that provides test doubles over the wire. Juggler allows to:

  • interact with mountebank API;
  • verify mocks;
  • alter and build imposters;

Only HTTP imposters are supported at the moment.

There is also Codeception module available.

Install

Via Composer

$ composer require meare/juggler:~1.0

Usage

API interactions

Juggler makes interactions with mountebank API easy:

use Meare\Juggler\Juggler;

$juggler = new Juggler('localhost');

// Delete active imposters before posting to avoid resource conflicts
$juggler->deleteImposters();
$port = $juggler->postImposterFromFile(__DIR__ . '/contract.json');

// Retrieve imposter contract and save it to file
$juggler->retrieveAndSaveContract($port, __DIR__ . '/retrieved_contract.json');

$juggler->deleteImposter($port);

Mock verification

mountebank remembers every request imposters get if --mock command line flag is set.

Here is how to verify mock with Juggler:

use Meare\Juggler\Juggler;

$juggler = new Juggler('localhost');

// Post imposter
$port = $juggler->postImposterFromFile(__DIR__ . '/contract.json');

// Do some requests
file_get_contents('http://mountebank:4545/foo?bar=1');
file_get_contents('http://mountebank:4545/foo?bar=2&zar=3');

// Retrieve imposter and verify it received requests
$imposter = $juggler->getHttpImposter($port);
$imposter->hasRequestsByCriteria([
    'method' => 'GET',
    'path'   => '/foo',
    'query'  => ['bar' => 1],
]); // Will return true

Read more on mock verification

Imposter altering

Imagine you have stub for GET /account/3 which returns account balance:

{
  "port": 4545,
  "protocol": "http",
  "stubs": [
    {
      "responses": [
        {
          "is": {
            "statusCode": 200,
            "body": {
              "clientId": 3,
              "name": "Dmitar Ekundayo",
              "balance": 24.5
            },
            "_mode": "text"
          }
        }
      ],
      "predicates": [
        {
          "equals": {
            "method": "GET",
            "path": "/client/3"
          }
        }
      ]
    }
  ]
}

At some point you might not want to create separate stub to imitate negative balance. Altering imposter will do the trick:

use Meare\Juggler\Juggler;

$juggler = new Juggler('localhost');
$port = $juggler->postImposterFromFile(__DIR__ . '/contract.json');

// Find stub by predicates and alter response
$imposter = $juggler->getHttpImposter($port);
$imposter->findStubByPredicates([['equals' => ['method' => 'GET', 'path' => '/account/3']]])
    ->getIsResponse()
    ->modifyBody(function (array $body) {
        $body['balance'] = -5.75;

        return $body;
    });

// Delete imposter and post again
$juggler->replaceImposter($imposter);

Building imposter

use Meare\Juggler\Imposter\HttpImposter;
use Meare\Juggler\Imposter\Stub\Predicate\Predicate;
use Meare\Juggler\Imposter\Stub\Response\IsResponse;
use Meare\Juggler\Juggler;

$juggler = new Juggler('localhost');

// Create imposter with a stub for GET /test-endpoint
$imposter = new HttpImposter;
$imposter->createStub(
    [new IsResponse(200, ['Content-type' => 'application/json'], '{"status":200}')],
    [new Predicate(Predicate::OPERATOR_EQUALS, ['method' => 'GET', 'path' => '/test-endpoint'])]
);

// Post it!
$juggler->postImposter($imposter);

Testing

$ composer test

Credits

License

The MIT License (MIT). Please see License File for more information.