 .../Core/Cache/Context/QueryArgsCacheContext.php   |  5 ++-
 .../Cache/Context/PathParentCacheContextTest.php   |  2 +-
 .../Cache/Context/QueryArgsCacheContextTest.php    | 46 ++++++++++++++++++++++
 3 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php b/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php
index 606e378..9b4eb0d 100644
--- a/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php
+++ b/core/lib/Drupal/Core/Cache/Context/QueryArgsCacheContext.php
@@ -27,8 +27,11 @@ public function getContext($query_arg = NULL) {
     if ($query_arg === NULL) {
       return $this->requestStack->getCurrentRequest()->getQueryString();
     }
+    elseif ($this->requestStack->getCurrentRequest()->query->has($query_arg)) {
+      return $this->requestStack->getCurrentRequest()->query->get($query_arg) ?: '?valueless?';
+    }
     else {
-      return $this->requestStack->getCurrentRequest()->query->get($query_arg);
+      return NULL;
     }
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Cache/Context/PathParentCacheContextTest.php b/core/tests/Drupal/Tests/Core/Cache/Context/PathParentCacheContextTest.php
index 2c44735..69120e2 100644
--- a/core/tests/Drupal/Tests/Core/Cache/Context/PathParentCacheContextTest.php
+++ b/core/tests/Drupal/Tests/Core/Cache/Context/PathParentCacheContextTest.php
@@ -18,7 +18,7 @@ class PathParentCacheContextTest extends UnitTestCase {
    *
    * @dataProvider providerTestGetContext
    */
-  public function testgetContext($original_path, $context) {
+  public function testGetContext($original_path, $context) {
     $request_stack = new RequestStack();
     $request = Request::create($original_path);
     $request_stack->push($request);
diff --git a/core/tests/Drupal/Tests/Core/Cache/Context/QueryArgsCacheContextTest.php b/core/tests/Drupal/Tests/Core/Cache/Context/QueryArgsCacheContextTest.php
new file mode 100644
index 0000000..93a11c5
--- /dev/null
+++ b/core/tests/Drupal/Tests/Core/Cache/Context/QueryArgsCacheContextTest.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\Tests\Core\Cache\Context;
+
+use Drupal\Core\Cache\Context\QueryArgsCacheContext;
+use Drupal\Tests\UnitTestCase;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\HttpFoundation\RequestStack;
+
+/**
+ * @coversDefaultClass \Drupal\Core\Cache\Context\QueryArgsCacheContext
+ * @group Cache
+ */
+class QueryArgsCacheContextTest extends UnitTestCase {
+
+  /**
+   * @covers ::getContext
+   *
+   * @dataProvider providerTestGetContext
+   */
+  public function testGetContext(array $query_args, $cache_context_parameter, $context) {
+    $request_stack = new RequestStack();
+    $request = Request::create('/', 'GET', $query_args);
+    $request_stack->push($request);
+    $cache_context = new QueryArgsCacheContext($request_stack);
+    $this->assertSame($cache_context->getContext($cache_context_parameter), $context);
+  }
+
+  /**
+   * Provides a list of query arguments and expected cache contexts.
+   */
+  public function providerTestGetContext() {
+    return [
+      [[], NULL, NULL],
+      [[], 'foo', NULL],
+      // Non-empty query arguments.
+      [['llama' => 'rocks', 'alpaca' => '', 'panda' => 'drools', 'z' => '0'], NULL, 'alpaca=&llama=rocks&panda=drools&z=0'],
+      [['llama' => 'rocks', 'alpaca' => '', 'panda' => 'drools', 'z' => '0'], 'llama', 'rocks'],
+      [['llama' => 'rocks', 'alpaca' => '', 'panda' => 'drools', 'z' => '0'], 'alpaca', '?valueless?'],
+      [['llama' => 'rocks', 'alpaca' => '', 'panda' => 'drools', 'z' => '0'], 'panda', 'drools'],
+      [['llama' => 'rocks', 'alpaca' => '', 'panda' => 'drools', 'z' => '0'], 'z', '0'],
+      [['llama' => 'rocks', 'alpaca' => '', 'panda' => 'drools', 'z' => '0'], 'chicken', NULL],
+    ];
+  }
+
+}
