diff --git a/tests/src/Unit/data_fetcher/HttpTest.php b/tests/src/Unit/data_fetcher/HttpTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..1332acafdbda57e6edfc6a5f3a04ccb0c0f25b83
--- /dev/null
+++ b/tests/src/Unit/data_fetcher/HttpTest.php
@@ -0,0 +1,241 @@
+<?php
+
+namespace Drupal\Tests\migrate_plus\Unit\data_fetcher;
+
+use Drupal\migrate\MigrateException;
+use Drupal\migrate_plus\DataFetcherPluginBase;
+use Drupal\migrate_plus\Plugin\migrate_plus\authentication\Basic;
+use Drupal\migrate_plus\Plugin\migrate_plus\data_fetcher\Http;
+use Drupal\Tests\migrate\Unit\MigrateTestCase;
+use GuzzleHttp\Client;
+use GuzzleHttp\Handler\MockHandler;
+use GuzzleHttp\HandlerStack;
+use GuzzleHttp\Psr7\Response;
+
+/**
+ * @file
+ * PHPUnit tests for the Migrate Plus Http 'data fetcher' plugin.
+ */
+
+/**
+ * @coversDefaultClass \Drupal\migrate_plus\Plugin\migrate_plus\data_fetcher\Http
+ *
+ * @group migrate_plus
+ */
+class HttpTest extends MigrateTestCase {
+
+  /**
+   * Minimal migration configuration data.
+   *
+   * @var array
+   */
+  private $specificMigrationConfig = [
+    'source' => 'url',
+    'urls' => ['http://example.org/http_fetcher_test'],
+    'data_fetcher_plugin' => 'http',
+    'data_parser_plugin' => 'json',
+    'item_selector' => 0,
+    'authentication' => [
+      'plugin' => 'basic',
+      'username' => 'testing',
+      'password' => 'password',
+    ],
+    'fields' => [],
+    'ids' => [
+      'id' => [
+        'type' => 'integer',
+      ],
+    ],
+  ];
+
+  /**
+   * The data fetcher plugin ID being tested.
+   *
+   * @var string
+   */
+  private $dataFetcherPluginId = 'http';
+
+  /**
+   * The data fetcher plugin definition.
+   *
+   * @var array
+   */
+  private $pluginDefinition = [
+    'id' => 'http',
+    'title' => 'HTTP',
+  ];
+
+  /**
+   * Test data to validate an HTTP response against.
+   *
+   * @var string
+   */
+  private $testData = '
+    {
+      "id": 1,
+      "name": "Joe Bloggs"
+    }
+  ';
+
+  /**
+   * Mocked up Basic authentication plugin.
+   *
+   * @var \PHPUnit_Framework_MockObject_MockObject
+   */
+  private $basicAuthenticator = NULL;
+
+  /**
+   * Set up test environment.
+   */
+  public function setUp() {
+    // Mock up a Basic authentication plugin that will be used in requests.
+    $basic_authenticator = $this->getMockBuilder(Basic::class)
+      ->disableOriginalConstructor()
+      ->getMock();
+
+    $basic_authenticator->method('getAuthenticationOptions')
+      ->will($this->returnValue([
+        'auth' => [
+          'username',
+          'password',
+        ],
+      ]));
+
+    $this->basicAuthenticator = $basic_authenticator;
+  }
+
+  /**
+   * Test 'http' data fetcher (with auth) returns an expected response.
+   */
+  public function testFetchHttpWithAuth() {
+    $migration_config = $this->migrationConfiguration + $this->specificMigrationConfig;
+
+    $plugin = new TestHttp($migration_config, $this->dataFetcherPluginId, $this->pluginDefinition);
+    $plugin->mockHttpClient([[200, 'application/json', $this->testData]], $this->basicAuthenticator);
+
+    // The Guzzle mock returns an instance of StreamInterface.
+    // http://docs.guzzlephp.org/en/latest/psr7.html
+    $stream = $plugin->getResponseContent($migration_config['urls'][0]);
+
+    $body = json_decode((string) $stream, TRUE);
+
+    // Compare what we got back from the parser to what we expected to get.
+    $expected = json_decode($this->testData, TRUE);
+    $this->assertArrayEquals($expected, $body);
+  }
+
+  /**
+   * Test 'http' data fetcher (without auth) returns an expected response.
+   */
+  public function testFetchHttpNoAuth() {
+    $migration_config = $this->migrationConfiguration + $this->specificMigrationConfig;
+    unset($migration_config['authentication']);
+
+    $plugin = new TestHttp($migration_config, $this->dataFetcherPluginId, $this->pluginDefinition);
+    $plugin->mockHttpClient([[200, 'application/json', $this->testData]], NULL);
+
+    $stream = $plugin->getResponseContent($migration_config['urls'][0]);
+
+    $body = json_decode((string) $stream, TRUE);
+
+    $expected = json_decode($this->testData, TRUE);
+    $this->assertArrayEquals($expected, $body);
+  }
+
+  /**
+   * Test 'http' data fetcher (with auth) dies as expected when auth fails.
+   */
+  public function testFetchHttpAuthFailure() {
+    $migration_config = $this->migrationConfiguration + $this->specificMigrationConfig;
+
+    $plugin = new TestHttp($migration_config, $this->dataFetcherPluginId, $this->pluginDefinition);
+    $plugin->mockHttpClient([[403, 'text/html', 'Forbidden']], $this->basicAuthenticator);
+
+    $this->setExpectedException(MigrateException::class, 'Error message: Client error: `GET http://example.org/http_fetcher_test` resulted in a `403 Forbidden');
+    $plugin->getResponseContent($migration_config['urls'][0]);
+  }
+
+  /**
+   * Test 'http' data fetcher (with auth) dies as expected when server down.
+   */
+  public function testFetchHttp500Error() {
+    $migration_config = $this->migrationConfiguration + $this->specificMigrationConfig;
+
+    $plugin = new TestHttp($migration_config, $this->dataFetcherPluginId, $this->pluginDefinition);
+    $plugin->mockHttpClient([[500, 'text/html', 'Internal Server Error']], $this->basicAuthenticator);
+
+    $this->setExpectedException(MigrateException::class, 'GET http://example.org/http_fetcher_test` resulted in a `500 Internal Server Error');
+    $plugin->getResponseContent($migration_config['urls'][0]);
+  }
+
+}
+/**
+ * @class Test class to mock an HTTP request.
+ */
+class TestHttp extends Http {
+
+  /**
+   * Mocked authenticator plugin.
+   *
+   * @var \PHPUnit_Framework_MockObject_MockObject
+   */
+  public $authenticator = NULL;
+
+  /**
+   * Mock the HttpClient, so we can control the request/response(s) etc.
+   *
+   * @param array $responses
+   *   An array of responses (arrays), with each consisting of properties,
+   *   ordered: response code, content-type and  response body.
+   * @param \PHPUnit_Framework_MockObject_MockObject $authenticator
+   *   Mocked authenticator plugin.
+   */
+  public function mockHttpClient($responses, $authenticator) {
+    // Set mocked authentication plugin to be used for the request auth plugin.
+    $this->authenticator = $authenticator;
+
+    $handler_responses = [];
+    foreach ($responses as $response) {
+      $handler_responses[] = new Response(
+        $response[0],
+        ['Content-Type' => $response[1]],
+        $response[2]
+      );
+    }
+
+    $mock = new MockHandler($handler_responses);
+    $handler = HandlerStack::create($mock);
+
+    $this->httpClient = new Client(['handler' => $handler]);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
+    // Skip calling the Http() constructor (that sets the httpClient instance
+    // variable via \Drupal which we don't want to do), but keep the call to its
+    // parent class constructor. @see https://bugs.php.net/bug.php?id=42016
+    DataFetcherPluginBase::__construct($configuration, $plugin_id, $plugin_definition);
+
+    // This is what the parent class is doing, that we need to override.
+    $this->httpClient = NULL;
+  }
+
+  /**
+   * Override the parent::getAuthenticationPlugin()
+   *
+   * So we can mock the authentication plugin.
+   *
+   * @return \PHPUnit_Framework_MockObject_MockObject
+   *   A mocked authentication plugin.
+   */
+  public function getAuthenticationPlugin() {
+    if (!isset($this->authenticationPlugin)) {
+      $this->authenticationPlugin = $this->authenticator;
+    }
+
+    return $this->authenticationPlugin;
+  }
+
+}