I am trying to use BrowserTestBase to write a functional test for a Form. The form populates some form elements with data retrieved from an external site. The client for this external site is injected into the form as a Drupal 8 service. The client uses Guzzle, and I'm building the mock client using code similar to the following one.
$myClient = new MyClient(Drupal::configFactory(), [ 'handler' => HandlerStack::create( new MockHandler([ new Response(200, ['X-Foo' => 'Bar'], 'Hello, World') ]) ), 'base_uri' => 'http://example.com/api/', ]);
I've tried doing this in the test class to assign my mock client to the service.
I've tried placing this assignment in
setUp() as well as the
testMyForm() method itself, but the container passed to the form's
create() method doesn't contain
After digging into the code I discovered that parameters and services may be initialized in the test-site context by adding them inside
testing.services.yml and placing that in the default site folder. In my test I used:
services: browser_test.handler_stack: class: GuzzleHttp\HandlerStack factory: GuzzleHttp\HandlerStack::create arguments: - '@browser_test.mock_handler' browser_test.mock_handler: class: GuzzleHttp\Handler\MockHandler my.service: class: Drupal\mymodule\Client\MyClient arguments: - '@config.factory' - base_uri: 'http://localhost/test/' handler: '@browser_test.handler_stack'
This overrode the client (which solves part of the problem), however I'm still unable to inject mock responses into
MockHandler from the test class. I tried:
/** @var MockHandler $handlerStack */ $handler = $this->container->get('browser_test.mock_handler'); $handler->append(new Response(200, ['X-Foo' => 'Bar'], 'Hello, World')); $this->drupalLogin($this->adminUser); $this->drupalGet('path/to/my_form'); $this->assertSession()->statusCodeEquals(200);
But MockHandler is throwing an exception because
Mock queue is empty.