diff --git a/core/modules/language/tests/src/Unit/Plugin/LanguageNegotiation/LanguageNegotiationBrowserTest.php b/core/modules/language/tests/src/Unit/Plugin/LanguageNegotiation/LanguageNegotiationBrowserTest.php
new file mode 100644
index 0000000000..686db85af4
--- /dev/null
+++ b/core/modules/language/tests/src/Unit/Plugin/LanguageNegotiation/LanguageNegotiationBrowserTest.php
@@ -0,0 +1,127 @@
+<?php
+
+namespace Drupal\Tests\language\Unit\Plugin\LanguageNegotiation;
+
+use Symfony\Component\HttpFoundation\Request;
+use Drupal\Core\Cache\Context\CacheContextsManager;
+use Drupal\Core\DependencyInjection\ContainerBuilder;
+use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\PageCache\ResponsePolicy\KillSwitch;
+use Drupal\Core\Session\AccountInterface;
+use Drupal\language\ConfigurableLanguageManagerInterface;
+use Drupal\Tests\UnitTestCase;
+use Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser;
+use Symfony\Component\HttpFoundation\ServerBag;
+
+/**
+ * Tests the LanguageNegotiationBrowser plugin class.
+ *
+ * @group language
+ * @coversDefaultClass \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser
+ * @see \Drupal\language\Plugin\LanguageNegotiation\LanguageNegotiationBrowser
+ */
+class LanguageNegotiationBrowserTest extends UnitTestCase {
+
+  /**
+   * A mock LanguageManager object.
+   *
+   * @var \Drupal\language\ConfigurableLanguageManagerInterface
+   */
+  protected $languageManager;
+
+  /**
+   * A mock object implementing the AccountInterface.
+   *
+   * @var \Drupal\Core\Session\AccountInterface
+   */
+  protected $user;
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function setUp() {
+
+    // Set up some languages to be used by the language-based path processor.
+    $language_de = $this->createMock(LanguageInterface::class);
+    $language_de->expects($this->any())
+      ->method('getId')
+      ->will($this->returnValue('de'));
+    $language_en = $this->createMock(LanguageInterface::class);
+    $language_en->expects($this->any())
+      ->method('getId')
+      ->will($this->returnValue('en'));
+    $languages = [
+      'de' => $language_de,
+      'en' => $language_en,
+    ];
+    $this->languages = $languages;
+
+    // Create a language manager stub.
+    $language_manager = $this->getMockBuilder(ConfigurableLanguageManagerInterface::class)
+      ->getMock();
+    $language_manager->expects($this->any())
+      ->method('getLanguages')
+      ->will($this->returnValue($languages));
+    $this->languageManager = $language_manager;
+
+    // Create a user stub.
+    $this->user = $this->getMockBuilder(AccountInterface::class)
+      ->getMock();
+
+    $cache_contexts_manager = $this->getMockBuilder(CacheContextsManager::class)
+      ->disableOriginalConstructor()
+      ->getMock();
+    $cache_contexts_manager->method('assertValidTokens')->willReturn(TRUE);
+    $container = new ContainerBuilder();
+    $container->set('cache_contexts_manager', $cache_contexts_manager);
+    \Drupal::setContainer($container);
+  }
+
+  /**
+   * @covers ::getLangcode
+   */
+  public function testGetLangcode() {
+
+    // KillSwitch be called every single time.
+    $killSwitchMock = $this->getMockBuilder(KillSwitch::class)->getMock();
+    $killSwitchMock->expects($this->any())
+      ->method('trigger');
+
+    $languageNegotiationBrowser = new LanguageNegotiationBrowser($killSwitchMock);
+
+    // Case 1: LanguageManager not available.
+    $expectedLangcode = NULL;
+    $this->assertEquals($expectedLangcode, $languageNegotiationBrowser->getLangcode());
+
+    // Case 2: LanguageManager available, but no request given.
+    $languageNegotiationBrowser->setLanguageManager($this->languageManager);
+    $expectedLangcode = NULL;
+    $this->assertEquals($expectedLangcode, $languageNegotiationBrowser->getLangcode());
+
+    // Case 3: LanguageManager available, a request is given, but
+    // HTTP_ACCEPT_LANGUAGE is not provided.
+    $request = Request::create('/de/foo', 'GET');
+    $request->server = new ServerBag();
+    $expectedLangcode = NULL;
+    $this->assertEquals($expectedLangcode, $languageNegotiationBrowser->getLangcode($request));
+
+    // Case 4: LanguageManager available, a request with HTTP_ACCEPT_LANGUAGE is
+    // provided, with a given langcode that is one of the system supported
+    // languages.
+    $expectedLangcode = 'de';
+    $request->server->set('HTTP_ACCEPT_LANGUAGE', 'de');
+    $config = $this->getConfigFactoryStub(['language.mappings' => ['map' => []]]);
+    $languageNegotiationBrowser->setConfig($config);
+    $this->assertEquals($expectedLangcode, $languageNegotiationBrowser->getLangcode($request));
+
+    // Case 5: LanguageManager available, a request with HTTP_ACCEPT_LANGUAGE is
+    // provided, with a given langcode that is not one of the system supported
+    // languages.
+    $expectedLangcode = 'it';
+    $request->server->set('HTTP_ACCEPT_LANGUAGE', 'it');
+    $config = $this->getConfigFactoryStub(['language.mappings' => ['map' => []]]);
+    $languageNegotiationBrowser->setConfig($config);
+    $this->assertFalse($languageNegotiationBrowser->getLangcode($request));
+  }
+
+}
