diff --git a/core/modules/system/tests/modules/batch_test/batch_test.module b/core/modules/system/tests/modules/batch_test/batch_test.module
index 2c1bee2..689b863 100644
--- a/core/modules/system/tests/modules/batch_test/batch_test.module
+++ b/core/modules/system/tests/modules/batch_test/batch_test.module
@@ -45,47 +45,41 @@ function batch_test_menu() {
   // drupal_form_submit().
   $items['batch-test/programmatic'] = array(
     'title' => 'Programmatic',
-    'page callback' => 'batch_test_programmatic',
-    'access callback' => TRUE,
+    'route_name' => 'batch_test_programmatic',
     'type' => MENU_LOCAL_TASK,
     'weight' => 3,
   );
   // No form: fire a batch simply by accessing a page.
   $items['batch-test/no-form'] = array(
     'title' => 'Simple page',
-    'page callback' => 'batch_test_no_form',
-    'access callback' => TRUE,
+    'route_name' => 'batch_test_no_form',
     'type' => MENU_LOCAL_TASK,
     'weight' => 4,
   );
   // No form: fire a batch; return > 100% complete
   $items['batch-test/large-percentage'] = array(
     'title' => 'Simple page with batch over 100% complete',
-    'page callback' => 'batch_test_large_percentage',
-    'access callback' => TRUE,
+    'route_name' => 'batch_test_large_percentage',
     'type' => MENU_LOCAL_TASK,
     'weight' => 5,
   );
   // Tests programmatic form submission within a batch operation.
   $items['batch-test/nested-programmatic'] = array(
     'title' => 'Nested programmatic',
-    'page callback' => 'batch_test_nested_drupal_form_submit',
-    'access callback' => TRUE,
+    'route_name' => 'batch_test_nested_programmatic',
     'type' => MENU_LOCAL_TASK,
     'weight' => 6,
   );
   // Landing page to test redirects.
   $items['batch-test/redirect'] = array(
     'title' => 'Redirect',
-    'page callback' => 'batch_test_redirect_page',
-    'access callback' => TRUE,
+    'route_name' => 'batch_test_redirect',
     'type' => MENU_LOCAL_TASK,
     'weight' => 7,
   );
   // This item lives under 'admin' so that the page uses the admin theme.
   $items['admin/batch-test/test-theme'] = array(
-    'page callback' => 'batch_test_theme_batch',
-    'access callback' => TRUE,
+    'route_name' => 'batch_test_test_theme',
     'type' => MENU_CALLBACK,
   );
 
@@ -275,29 +269,6 @@ function batch_test_chained_form_submit_4($form, &$form_state) {
 }
 
 /**
- * Menu callback: Submits the 'Chained' form programmatically.
- */
-function batch_test_programmatic($value = 1) {
-  $form_state = array(
-    'values' => array('value' => $value)
-  );
-  drupal_form_submit('batch_test_chained_form', $form_state);
-  return 'Got out of a programmatic batched form.';
-}
-
-/**
- * Menu callback: Submits a form within a batch programmatically.
- */
-function batch_test_nested_drupal_form_submit($value = 1) {
-  // Set the batch and process it.
-  $batch['operations'] = array(
-    array('_batch_test_nested_drupal_form_submit_callback', array($value)),
-  );
-  batch_set($batch);
-  return batch_process('batch-test/redirect');
-}
-
-/**
  * Batch operation: Submits form_test_mock_form() using drupal_form_submit().
  */
 function _batch_test_nested_drupal_form_submit_callback($value) {
@@ -332,33 +303,6 @@ function batch_test_mock_form_submit($form, &$form_state) {
 }
 
 /**
- * Menu callback: Fires a batch process without a form submission.
- */
-function batch_test_no_form() {
-  batch_test_stack(NULL, TRUE);
-
-  batch_set(_batch_test_batch_1());
-  return batch_process('batch-test/redirect');
-}
-
-/**
- * Menu callback: Fires a batch process without a form submission.
- */
-function batch_test_large_percentage() {
-  batch_test_stack(NULL, TRUE);
-
-  batch_set(_batch_test_batch_5());
-  return batch_process('batch-test/redirect');
-}
-
-/**
- * Menu callback: Redirects successfuly.
- */
-function batch_test_redirect_page() {
-  return 'Redirection successful.';
-}
-
-/**
  * Batch 0: Does nothing.
  */
 function _batch_test_batch_0() {
@@ -496,20 +440,6 @@ function _batch_test_batch_5() {
 }
 
 /**
- * Menu callback: Runs a batch for testing theme used on the progress page.
- */
-function batch_test_theme_batch() {
-  batch_test_stack(NULL, TRUE);
-  $batch = array(
-    'operations' => array(
-      array('_batch_test_theme_callback', array()),
-    ),
-  );
-  batch_set($batch);
-  return batch_process('batch-test/redirect');
-}
-
-/**
  * Tests the progress page theme by performing a batch callback.
  */
 function _batch_test_theme_callback() {
diff --git a/core/modules/system/tests/modules/batch_test/batch_test.routing.yml b/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
new file mode 100644
index 0000000..38e279d
--- /dev/null
+++ b/core/modules/system/tests/modules/batch_test/batch_test.routing.yml
@@ -0,0 +1,41 @@
+batch_test_redirect:
+  pattern: 'batch-test/redirect'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testRedirect'
+  requirements:
+    _access:  'TRUE'
+
+batch_test_large_percentage:
+  pattern: 'batch-test/large-percentage'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testLargePercentage'
+  requirements:
+    _access:  'TRUE'
+
+batch_test_nested_programmatic:
+  pattern: 'batch-test/nested-programmatic/{value}'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testNestedDrupalFormSubmit'
+  requirements:
+    _access: 'TRUE'
+
+batch_test_no_form:
+  pattern: 'batch-test/no-form'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testNoForm'
+  requirements:
+    _access: 'TRUE'
+
+batch_test_programmatic:
+  pattern: 'batch-test/programmatic/{value}'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testProgrammatic'
+  requirements:
+    _access: 'TRUE'
+
+batch_test_test_theme:
+  pattern: 'admin/batch-test/test-theme'
+  defaults:
+    _content: '\Drupal\batch_test\Controller\BatchTestController::testThemeBatch'
+  requirements:
+    _access: 'TRUE'
diff --git a/core/modules/system/tests/modules/batch_test/lib/Drupal/batch_test/Controller/BatchTestController.php b/core/modules/system/tests/modules/batch_test/lib/Drupal/batch_test/Controller/BatchTestController.php
new file mode 100644
index 0000000..405e88d
--- /dev/null
+++ b/core/modules/system/tests/modules/batch_test/lib/Drupal/batch_test/Controller/BatchTestController.php
@@ -0,0 +1,102 @@
+<?php
+/**
+ * @file
+ * Contains \Drupal\batch_test\Controller\BatchTestController.
+ */
+
+namespace Drupal\batch_test\Controller;
+
+use Drupal\Core\Controller\ControllerInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Controller routines for batch tests.
+ */
+class BatchTestController implements ControllerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container) {
+    return new static();
+  }
+
+  /**
+   * Menu callback: Redirects successfuly.
+   */
+  public function testRedirect() {
+    return array(
+      'success' => array(
+        '#type' => 'markup',
+        '#markup' => 'Redirection successful.',
+      )
+    );
+  }
+
+  /**
+   * Fires a batch process without a form submission.
+   */
+  public function testLargePercentage() {
+    batch_test_stack(NULL, TRUE);
+
+    batch_set(_batch_test_batch_5());
+    return batch_process('batch-test/redirect');
+  }
+
+  /**
+   * Menu callback: Submits a form within a batch programmatically.
+   */
+  public function testNestedDrupalFormSubmit($value = 1) {
+    // Set the batch and process it.
+    $batch['operations'] = array(
+      array('_batch_test_nested_drupal_form_submit_callback', array($value)),
+    );
+    batch_set($batch);
+    return batch_process('batch-test/redirect');
+  }
+
+  /**
+   * Menu callback: Fires a batch process without a form submission.
+   */
+  public function testNoForm() {
+    batch_test_stack(NULL, TRUE);
+
+    batch_set(_batch_test_batch_1());
+    return batch_process('batch-test/redirect');
+
+  }
+
+  /**
+   * Menu callback: Submits the 'Chained' form programmatically.
+   *
+   * Programmatic form: the page submits the 'Chained' form through
+   * drupal_form_submit().
+   */
+  function testProgrammatic($value = 1) {
+    $form_state = array(
+      'values' => array('value' => $value)
+    );
+    drupal_form_submit('batch_test_chained_form', $form_state);
+    return array(
+      'success' => array(
+        '#type' => 'markup',
+        '#markup' => 'Got out of a programmatic batched form.',
+      )
+    );
+  }
+
+  /**
+   * Menu callback: Runs a batch for testing theme used on the progress page.
+   */
+  public function testThemeBatch() {
+    batch_test_stack(NULL, TRUE);
+    $batch = array(
+      'operations' => array(
+        array('_batch_test_theme_callback', array()),
+      ),
+    );
+    batch_set($batch);
+    return batch_process('batch-test/redirect');
+  }
+
+}
