diff --git a/plugins/task/checkfiles/checkfiles.xml b/plugins/task/checkfiles/checkfiles.xml
index 2a3cbb4f2be36..61c94a5dd9ae3 100644
--- a/plugins/task/checkfiles/checkfiles.xml
+++ b/plugins/task/checkfiles/checkfiles.xml
@@ -9,9 +9,10 @@
 	www.joomla.org
 	4.1
 	PLG_TASK_CHECK_FILES_XML_DESCRIPTION
+	Joomla\Plugin\Task\Checkfiles
 	
-		checkfiles.php
-		language
+		services
+		src
 		forms
 	
 	
diff --git a/plugins/task/checkfiles/services/provider.php b/plugins/task/checkfiles/services/provider.php
new file mode 100644
index 0000000000000..2a518e2f0571e
--- /dev/null
+++ b/plugins/task/checkfiles/services/provider.php
@@ -0,0 +1,48 @@
+
+ * @license     GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+defined('_JEXEC') or die;
+
+use Joomla\CMS\Extension\PluginInterface;
+use Joomla\CMS\Factory;
+use Joomla\CMS\Plugin\PluginHelper;
+use Joomla\DI\Container;
+use Joomla\DI\ServiceProviderInterface;
+use Joomla\Event\DispatcherInterface;
+use Joomla\Plugin\Task\Checkfiles\Extension\Checkfiles;
+
+return new class implements ServiceProviderInterface
+{
+    /**
+     * Registers the service provider with a DI container.
+     *
+     * @param   Container  $container  The DI container.
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function register(Container $container)
+    {
+        $container->set(
+            PluginInterface::class,
+            function (Container $container) {
+                $plugin = new Checkfiles(
+                    $container->get(DispatcherInterface::class),
+                    (array) PluginHelper::getPlugin('task', 'checkfiles'),
+                    JPATH_ROOT . '/images/'
+                );
+                $plugin->setApplication(Factory::getApplication());
+
+                return $plugin;
+            }
+        );
+    }
+};
diff --git a/plugins/task/checkfiles/checkfiles.php b/plugins/task/checkfiles/src/Extension/Checkfiles.php
similarity index 61%
rename from plugins/task/checkfiles/checkfiles.php
rename to plugins/task/checkfiles/src/Extension/Checkfiles.php
index d8505700bef0c..50a8f85ed5fff 100644
--- a/plugins/task/checkfiles/checkfiles.php
+++ b/plugins/task/checkfiles/src/Extension/Checkfiles.php
@@ -6,19 +6,20 @@
  *
  * @copyright   (C) 2021 Open Source Matters, Inc. 
  * @license     GNU General Public License version 2 or later; see LICENSE.txt
-
- * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace
  */
 
-use Joomla\CMS\Filesystem\Folder;
+namespace Joomla\Plugin\Task\Checkfiles\Extension;
+
 use Joomla\CMS\Image\Image;
-use Joomla\CMS\Language\Text;
 use Joomla\CMS\Plugin\CMSPlugin;
 use Joomla\Component\Scheduler\Administrator\Event\ExecuteTaskEvent;
 use Joomla\Component\Scheduler\Administrator\Task\Status as TaskStatus;
 use Joomla\Component\Scheduler\Administrator\Traits\TaskPluginTrait;
+use Joomla\Event\DispatcherInterface;
 use Joomla\Event\SubscriberInterface;
+use Joomla\Filesystem\Folder;
 use Joomla\Filesystem\Path;
+use LogicException;
 
 /**
  * Task plugin with routines that offer checks on files.
@@ -26,7 +27,7 @@
  *
  * @since  4.1.0
  */
-class PlgTaskCheckfiles extends CMSPlugin implements SubscriberInterface
+final class Checkfiles extends CMSPlugin implements SubscriberInterface
 {
     use TaskPluginTrait;
 
@@ -43,12 +44,6 @@ class PlgTaskCheckfiles extends CMSPlugin implements SubscriberInterface
         ],
     ];
 
-    /**
-     * @var boolean
-     * @since 4.1.0
-     */
-    protected $autoloadLanguage = true;
-
     /**
      * @inheritDoc
      *
@@ -65,6 +60,36 @@ public static function getSubscribedEvents(): array
         ];
     }
 
+    /**
+     * @var boolean
+     * @since 4.1.0
+     */
+    protected $autoloadLanguage = true;
+
+    /**
+     * The root directory path
+     *
+     * @var    string
+     * @since  __DEPLOY_VERSION__
+     */
+    private $rootDirectory;
+
+    /**
+     * Constructor.
+     *
+     * @param   DispatcherInterface  $dispatcher     The dispatcher
+     * @param   array                $config         An optional associative array of configuration settings
+     * @param   string               $rootDirectory  The root directory to look for images
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function __construct(DispatcherInterface $dispatcher, array $config, string $rootDirectory)
+    {
+        parent::__construct($dispatcher, $config);
+
+        $this->rootDirectory = $rootDirectory;
+    }
+
     /**
      * @param   ExecuteTaskEvent  $event  The onExecuteTask event
      *
@@ -76,22 +101,19 @@ public static function getSubscribedEvents(): array
      */
     protected function checkImages(ExecuteTaskEvent $event): int
     {
-        $params = $event->getArgument('params');
-
-        $path      = Path::check(JPATH_ROOT . '/images/' . $params->path);
+        $params    = $event->getArgument('params');
+        $path      = Path::check($this->rootDirectory . $params->path);
         $dimension = $params->dimension;
         $limit     = $params->limit;
         $numImages = max(1, (int) $params->numImages ?? 1);
 
-        if (!Folder::exists($path)) {
-            $this->logTask(Text::_('PLG_TASK_CHECK_FILES_LOG_IMAGE_PATH_NA'), 'warning');
+        if (!is_dir($path)) {
+            $this->logTask($this->getApplication()->getLanguage()->_('PLG_TASK_CHECK_FILES_LOG_IMAGE_PATH_NA'), 'warning');
 
             return TaskStatus::NO_RUN;
         }
 
-        $images = Folder::files($path, '^.*\.(jpg|jpeg|png|gif|webp)', 2, true);
-
-        foreach ($images as $imageFilename) {
+        foreach (Folder::files($path, '^.*\.(jpg|jpeg|png|gif|webp)', 2, true) as $imageFilename) {
             $properties = Image::getImageFileProperties($imageFilename);
             $resize     = $properties->$dimension > $limit;
 
@@ -105,23 +127,29 @@ protected function checkImages(ExecuteTaskEvent $event): int
             $newHeight = $dimension === 'height' ? $limit : $height * $limit / $width;
             $newWidth  = $dimension === 'width' ? $limit : $width * $limit / $height;
 
-            $this->logTask(Text::sprintf('PLG_TASK_CHECK_FILES_LOG_RESIZING_IMAGE', $width, $height, $newWidth, $newHeight, $imageFilename));
+            $this->logTask(sprintf(
+                $this->getApplication()->getLanguage()->_('PLG_TASK_CHECK_FILES_LOG_RESIZING_IMAGE'),
+                $width,
+                $height,
+                $newWidth,
+                $newHeight,
+                $imageFilename
+            ));
 
             $image = new Image($imageFilename);
 
             try {
                 $image->resize($newWidth, $newHeight, false);
             } catch (LogicException $e) {
-                $this->logTask('PLG_TASK_CHECK_FILES_LOG_RESIZE_FAIL', 'error');
-                $resizeFail = true;
-            }
+                $this->logTask($this->getApplication()->getLanguage()->_('PLG_TASK_CHECK_FILES_LOG_RESIZE_FAIL'), 'error');
 
-            if (!empty($resizeFail)) {
                 return TaskStatus::KNOCKOUT;
             }
 
             if (!$image->toFile($imageFilename, $properties->type)) {
-                $this->logTask('PLG_TASK_CHECK_FILES_LOG_IMAGE_SAVE_FAIL', 'error');
+                $this->logTask($this->getApplication()->getLanguage()->_('PLG_TASK_CHECK_FILES_LOG_IMAGE_SAVE_FAIL'), 'error');
+
+                return TaskStatus::KNOCKOUT;
             }
 
             --$numImages;
diff --git a/tests/Unit/Plugin/Task/Checkfiles/Extension/CheckfilesPluginTest.php b/tests/Unit/Plugin/Task/Checkfiles/Extension/CheckfilesPluginTest.php
new file mode 100644
index 0000000000000..cd406a7881d2f
--- /dev/null
+++ b/tests/Unit/Plugin/Task/Checkfiles/Extension/CheckfilesPluginTest.php
@@ -0,0 +1,220 @@
+
+ * @license     GNU General Public License version 2 or later; see LICENSE.txt
+ */
+
+namespace Joomla\Tests\Unit\Plugin\Task\Checkfiles\Extension;
+
+use Joomla\CMS\Application\CMSApplicationInterface;
+use Joomla\CMS\Language\Language;
+use Joomla\Component\Scheduler\Administrator\Event\ExecuteTaskEvent;
+use Joomla\Component\Scheduler\Administrator\Task\Status;
+use Joomla\Component\Scheduler\Administrator\Task\Task;
+use Joomla\Event\Dispatcher;
+use Joomla\Filesystem\Folder;
+use Joomla\Plugin\Task\Checkfiles\Extension\Checkfiles;
+use Joomla\Tests\Unit\UnitTestCase;
+
+/**
+ * Test class for Checkfiles plugin
+ *
+ * @package     Joomla.UnitTest
+ * @subpackage  Checkfiles
+ *
+ * @testdox     The Checkfiles plugin
+ *
+ * @since       __DEPLOY_VERSION__
+ */
+class CheckfilesPluginTest extends UnitTestCase
+{
+    /**
+     * Setup
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function setUp(): void
+    {
+        if (!is_dir(__DIR__ . '/tmp')) {
+            mkdir(__DIR__ . '/tmp');
+        }
+
+        $image = imagecreate(200, 200);
+        imagecolorallocate($image, 255, 255, 0);
+        imagepng($image, __DIR__ . '/tmp/test.png');
+        imagedestroy($image);
+    }
+
+    /**
+     * Cleanup
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function tearDown(): void
+    {
+        if (is_dir(__DIR__ . '/tmp')) {
+            Folder::delete(__DIR__ . '/tmp');
+        }
+    }
+
+    /**
+     * @testdox  can resize an image
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function testResize()
+    {
+        $language = $this->createStub(Language::class);
+        $language->method('_')->willReturn('test');
+
+        $app = $this->createStub(CMSApplicationInterface::class);
+        $app->method('getLanguage')->willReturn($language);
+
+        $plugin = new Checkfiles(new Dispatcher(), [], __DIR__);
+        $plugin->setApplication($app);
+
+        $task = $this->createStub(Task::class);
+        $task->method('get')->willReturnMap([['id', null, 1], ['type', null, 'checkfiles.imagesize']]);
+
+        $event = new ExecuteTaskEvent(
+            'test',
+            [
+                'subject' => $task,
+                'params' => (object)['path' => '/tmp', 'dimension' => 'width', 'limit' => 20, 'numImages' => 1]
+            ]
+        );
+        $plugin->standardRoutineHandler($event);
+
+        $this->assertEquals(Status::OK, $event->getResultSnapshot()['status']);
+
+        list($width, $height) = getimagesize(__DIR__ . '/tmp/test.png');
+        $this->assertEquals(20, $width);
+        $this->assertEquals(20, $height);
+    }
+
+    /**
+     * @testdox  can resize a subset of images
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function testResizeWithLimit()
+    {
+        copy(__DIR__ . '/tmp/test.png', __DIR__ . '/tmp/test1.png');
+
+        $language = $this->createStub(Language::class);
+        $language->method('_')->willReturn('test');
+
+        $app = $this->createStub(CMSApplicationInterface::class);
+        $app->method('getLanguage')->willReturn($language);
+
+        $plugin = new Checkfiles(new Dispatcher(), [], __DIR__);
+        $plugin->setApplication($app);
+
+        $task = $this->createStub(Task::class);
+        $task->method('get')->willReturnMap([['id', null, 1], ['type', null, 'checkfiles.imagesize']]);
+
+        $event = new ExecuteTaskEvent(
+            'test',
+            [
+                'subject' => $task,
+                'params' => (object)['path' => '/tmp', 'dimension' => 'width', 'limit' => 20, 'numImages' => 1]
+            ]
+        );
+        $plugin->standardRoutineHandler($event);
+
+        $this->assertEquals(Status::OK, $event->getResultSnapshot()['status']);
+
+        list($width, $height) = getimagesize(__DIR__ . '/tmp/test.png');
+        $this->assertEquals(20, $width);
+        $this->assertEquals(20, $height);
+
+        list($width, $height) = getimagesize(__DIR__ . '/tmp/test1.png');
+        $this->assertEquals(200, $width);
+        $this->assertEquals(200, $height);
+    }
+
+    /**
+     * @testdox  can resize an image
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function testIgnoreResize()
+    {
+        $language = $this->createStub(Language::class);
+        $language->method('_')->willReturn('test');
+
+        $app = $this->createStub(CMSApplicationInterface::class);
+        $app->method('getLanguage')->willReturn($language);
+
+        $plugin = new Checkfiles(new Dispatcher(), [], __DIR__);
+        $plugin->setApplication($app);
+
+        $task = $this->createStub(Task::class);
+        $task->method('get')->willReturnMap([['id', null, 1], ['type', null, 'checkfiles.imagesize']]);
+
+        $event = new ExecuteTaskEvent(
+            'test',
+            [
+                'subject' => $task,
+                'params' => (object)['path' => '/tmp', 'dimension' => 'width', 'limit' => 2000, 'numImages' => 1]
+            ]
+        );
+        $plugin->standardRoutineHandler($event);
+
+        $this->assertEquals(Status::OK, $event->getResultSnapshot()['status']);
+
+        list($width, $height) = getimagesize(__DIR__ . '/tmp/test.png');
+        $this->assertEquals(200, $width);
+        $this->assertEquals(200, $height);
+    }
+
+    /**
+     * @testdox  can not run when invalid folder
+     *
+     * @return  void
+     *
+     * @since   __DEPLOY_VERSION__
+     */
+    public function testInvalidFolder()
+    {
+        $language = $this->createStub(Language::class);
+        $language->method('_')->willReturn('test');
+
+        $app = $this->createStub(CMSApplicationInterface::class);
+        $app->method('getLanguage')->willReturn($language);
+
+        $plugin = new Checkfiles(new Dispatcher(), [], __DIR__);
+        $plugin->setApplication($app);
+
+        $task = $this->createStub(Task::class);
+        $task->method('get')->willReturnMap([['id', null, 1], ['type', null, 'checkfiles.imagesize']]);
+
+        $event = new ExecuteTaskEvent(
+            'test',
+            [
+                'subject' => $task,
+                'params' => (object)['path' => '/invalid', 'dimension' => 'width', 'limit' => 20, 'numImages' => 1]
+            ]
+        );
+        $plugin->standardRoutineHandler($event);
+
+        list($width, $height) = getimagesize(__DIR__ . '/tmp/test.png');
+        $this->assertEquals(Status::NO_RUN, $event->getResultSnapshot()['status']);
+        $this->assertEquals(200, $width);
+        $this->assertEquals(200, $height);
+    }
+}