diff --git a/tests/src/Functional/StatusCheckTest.php b/tests/src/Functional/StatusCheckTest.php
index e934646bd6f4a039d11f7302b038f54fc6672355..e9391488904c2811e1a1a0537b3b8131c18c0dd4 100644
--- a/tests/src/Functional/StatusCheckTest.php
+++ b/tests/src/Functional/StatusCheckTest.php
@@ -7,7 +7,6 @@ namespace Drupal\Tests\automatic_updates\Functional;
 use Behat\Mink\Element\NodeElement;
 use Drupal\automatic_updates\CronUpdateStage;
 use Drupal\automatic_updates\StatusCheckMailer;
-use Drupal\automatic_updates_test\Datetime\TestTime;
 use Drupal\automatic_updates_test\EventSubscriber\TestSubscriber1;
 use Drupal\automatic_updates_test_status_checker\EventSubscriber\TestSubscriber2;
 use Drupal\Core\Url;
@@ -142,8 +141,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
 
     // Confirm a user without the permission to run status checks does not
     // have a link to run the checks when the checks need to be run again.
-    // @todo Change this to fake the request time in
-    //   https://www.drupal.org/node/3113971.
     /** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */
     $key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates');
     $key_value->delete('status_check_last_run');
@@ -247,7 +244,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
   }
 
   /**
-   * Tests status check results on admin pages..
+   * Tests status check results on admin pages.
    *
    * @param string $admin_route
    *   The admin route to check.
@@ -271,9 +268,6 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
     // a link to run the checks when the checks need to be run again.
     $expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_ERROR)];
     TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
-    // @todo Change this to use ::delayRequestTime() to simulate running cron
-    //   after a 24 wait instead of directly deleting 'status_check_last_run'
-    //   https://www.drupal.org/node/3113971.
     /** @var \Drupal\Core\KeyValueStore\KeyValueStoreInterface $key_value */
     $key_value = $this->container->get('keyvalue.expirable')->get('automatic_updates');
     $key_value->delete('status_check_last_run');
@@ -297,9 +291,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
       '1 warning' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING),
     ];
     TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
-    // Confirm a new message is displayed if the cron is run after an hour.
-    $this->delayRequestTime();
-    $this->cronRun();
+    $this->runStatusChecks();
     $this->drupalGet(Url::fromRoute($admin_route));
     $assert->pageTextContainsOnce(static::$errorsExplanation);
     // Confirm on admin pages that the summary will be displayed.
@@ -311,25 +303,22 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
     $assert->pageTextNotContains($expected_results['1 warning']->messages[0]);
     $assert->pageTextNotContains($expected_results['1 warning']->summary);
 
-    // Confirm that if cron runs less than hour after it previously ran it will
-    // not run the checkers again.
+    // Confirm the status check event is not dispatched on every admin page
+    // load.
     $unexpected_results = [
       '2 errors' => $this->createValidationResult(SystemManager::REQUIREMENT_ERROR, 2),
       '2 warnings' => $this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2),
     ];
     TestSubscriber1::setTestResult($unexpected_results, StatusCheckEvent::class);
-    $this->delayRequestTime(30);
-    $this->cronRun();
     $this->drupalGet(Url::fromRoute($admin_route));
     $assert->pageTextNotContains($unexpected_results['2 errors']->summary);
     $assert->pageTextContainsOnce((string) $expected_results['1 error']->summary);
     $assert->pageTextNotContains($unexpected_results['2 warnings']->summary);
     $assert->pageTextNotContains($expected_results['1 warning']->messages[0]);
 
-    // Confirm that is if cron is run over an hour after the checkers were
-    // previously run the checkers will be run again.
-    $this->delayRequestTime(31);
-    $this->cronRun();
+    // Confirm the updated results will be shown when status checks are run
+    // again.
+    $this->runStatusChecks();
     $expected_results = $unexpected_results;
     $this->drupalGet(Url::fromRoute($admin_route));
     // Confirm on admin pages only the error summary will be displayed if there
@@ -347,8 +336,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
 
     $expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING, 2)];
     TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
-    $this->delayRequestTime();
-    $this->cronRun();
+    $this->runStatusChecks();
     $this->drupalGet(Url::fromRoute($admin_route));
     // Confirm that the warnings summary is displayed on admin pages if there
     // are no errors.
@@ -361,8 +349,7 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
 
     $expected_results = [$this->createValidationResult(SystemManager::REQUIREMENT_WARNING)];
     TestSubscriber1::setTestResult($expected_results, StatusCheckEvent::class);
-    $this->delayRequestTime();
-    $this->cronRun();
+    $this->runStatusChecks();
     $this->drupalGet(Url::fromRoute($admin_route));
     $assert->pageTextNotContains(static::$errorsExplanation);
     // Confirm that a single warning is displayed and not the summary on admin
@@ -761,15 +748,11 @@ class StatusCheckTest extends AutomaticUpdatesFunctionalTestBase {
   }
 
   /**
-   * Delays the request for the test.
-   *
-   * @param int $minutes
-   *   The number of minutes to delay request time. Defaults to 61 minutes.
+   * Runs status checks.
    */
-  private function delayRequestTime(int $minutes = 61): void {
-    static $total_delay = 0;
-    $total_delay += $minutes;
-    TestTime::setFakeTimeByOffset("+$total_delay minutes");
+  private function runStatusChecks(): void {
+    $this->drupalGet('/admin/reports/status');
+    $this->clickLink('Rerun readiness checks');
   }
 
 }
diff --git a/tests/src/Kernel/HookCronTest.php b/tests/src/Kernel/HookCronTest.php
index b4b2e845f207985220c0bdfdb04c10904537a402..a81fda6a72b05eac2b2aebea2439cd3b3236ad88 100644
--- a/tests/src/Kernel/HookCronTest.php
+++ b/tests/src/Kernel/HookCronTest.php
@@ -2,7 +2,9 @@
 
 namespace Drupal\Tests\automatic_updates\Kernel;
 
-use Drupal\automatic_updates\Validation\StatusChecker;
+use Drupal\automatic_updates\CronUpdateStage;
+use Drupal\automatic_updates_test\Datetime\TestTime;
+use Drupal\package_manager\Event\StatusCheckEvent;
 
 /**
  * @group automatic_updates
@@ -12,25 +14,47 @@ class HookCronTest extends AutomaticUpdatesKernelTestBase {
   /**
    * {@inheritdoc}
    */
-  protected static $modules = ['automatic_updates'];
+  protected static $modules = ['automatic_updates', 'automatic_updates_test'];
 
   /**
-   * Tests that our cron hook does not run if we're at the command line.
+   * Tests that our cron hook will run status checks.
    */
-  public function testCronHookBypassedAtCommandLine(): void {
-    if (PHP_SAPI !== 'cli') {
-      $this->markTestSkipped('This test requires that PHP be running at the command line.');
-    }
-
-    // The status check should not have run yet.
-    /** @var \Drupal\automatic_updates\Validation\StatusChecker $status_checker */
-    $status_checker = $this->container->get(StatusChecker::class);
-    $this->assertNull($status_checker->getLastRunTime());
+  public function testStatusChecksRunOnCron(): void {
+    // Set the core version to 9.8.1 so there will not be an update attempted.
+    // The hook_cron implementations will not be run if there is an update.
+    // @see \Drupal\automatic_updates\CronUpdateStage::run()
+    // @todo Remove this is https://drupal.org/i/3357969
+    $this->setCoreVersion('9.8.1');
+    // Undo override of the 'serverApi' property from the parent test class.
+    // @see \Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase::setUp
+    $property = new \ReflectionProperty(CronUpdateStage::class, 'serverApi');
+    $property->setValue(NULL, 'cli');
+    $this->assertTrue(CronUpdateStage::isCommandLine());
+    $status_check_count = 0;
+    $this->addEventTestListener(function () use (&$status_check_count) {
+      $status_check_count++;
+    }, StatusCheckEvent::class);
 
     // Since we're at the command line, status checks should still not run, even
     // if we do run cron.
     $this->container->get('cron')->run();
-    $this->assertNull($status_checker->getResults());
+    $this->assertSame(0, $status_check_count);
+
+    // If we are on the web the status checks should run.
+    $property->setValue(NULL, 'cgi-fcgi');
+    $this->assertFalse(CronUpdateStage::isCommandLine());
+    $this->container->get('cron')->run();
+    $this->assertSame(1, $status_check_count);
+
+    // Ensure that the status checks won't run if less than an hour has passed.
+    TestTime::setFakeTimeByOffset("+30 minutes");
+    $this->container->get('cron')->run();
+    $this->assertSame(1, $status_check_count);
+
+    // The status checks should run if more than an hour has passed.
+    TestTime::setFakeTimeByOffset("+61 minutes");
+    $this->container->get('cron')->run();
+    $this->assertSame(2, $status_check_count);
   }
 
 }