diff --git a/lib/classes/ActionMenu.php b/lib/classes/ActionMenu.php
index f7ec8881bb520405b287373507b7c2b6d1a12f1b..6fc016a2e7c2946b7fcd08b5c7e17ff6f1ef1c1d 100644
--- a/lib/classes/ActionMenu.php
+++ b/lib/classes/ActionMenu.php
@@ -11,6 +11,9 @@ class ActionMenu
     const TEMPLATE_FILE_SINGLE   = 'shared/action-menu-single.php';
     const TEMPLATE_FILE_MULTIPLE = 'shared/action-menu.php';
 
+    const RENDERING_MODE_ICONS = 'icons';
+    const RENDERING_MODE_MENU = 'menu';
+
     /**
      * Returns an instance.
      *
@@ -32,6 +35,10 @@ class ActionMenu
      */
     protected $context = '';
 
+    /**
+     * @var string|null $rendering_mode The forced rendering mode
+     */
+    protected $rendering_mode = null;
 
     /**
      * Private constructur.
@@ -248,10 +255,10 @@ class ActionMenu
             return '';
         }
 
-        $template_file = count($this->actions) <= Config::get()->ACTION_MENU_THRESHOLD
+        $template_file = $this->getRenderingMode() === self::RENDERING_MODE_ICONS
                        ? self::TEMPLATE_FILE_SINGLE
                        : self::TEMPLATE_FILE_MULTIPLE;
-
+;
         $template = $GLOBALS['template_factory']->open($template_file);
         $template->actions = array_map(function ($action) {
             $disabled = isset($action['attributes']['disabled'])
@@ -287,7 +294,6 @@ class ActionMenu
         return null;
     }
 
-
     /**
      * Sets the context for the menu.
      *
@@ -302,6 +308,47 @@ class ActionMenu
         return $this;
     }
 
+    /**
+     * Forces an explicit rendering mode.
+     *
+     * @param string|null $mode The desired rendering mode or null for automatic detection
+     * @return ActionMenu The action menu instance to allow chaining
+     * @throws Exception
+     */
+    public function setRenderingMode(?string $mode): ActionMenu
+    {
+        if (
+            $mode !== null
+            && $mode !== self::RENDERING_MODE_ICONS
+            && $mode !== self::RENDERING_MODE_MENU
+        ) {
+            throw new Exception("Invalid rendering mode '{$mode}'");
+        }
+
+        $this->rendering_mode = $mode;
+
+        return $this;
+    }
+
+    /**
+     * Returns the rendering mode for this action menu. This is set by either
+     * calling setRenderingMode or automatically determined by the configured
+     * threshold.
+     *
+     * @return string
+     */
+    public function getRenderingMode(): string
+    {
+        $rendering_mode = $this->rendering_mode;
+
+        if ($rendering_mode === null) {
+            $rendering_mode = count($this->actions) <= Config::get()->ACTION_MENU_THRESHOLD
+                            ? self::RENDERING_MODE_ICONS
+                            : self::RENDERING_MODE_MENU;
+        }
+
+        return $rendering_mode;
+    }
 
     /**
      * Generates the title of the action menu, including its context, if the context has been set.
diff --git a/tests/unit/lib/classes/ActionMenuTest.php b/tests/unit/lib/classes/ActionMenuTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..ece2c4e8b4d467ee9edd9e588d7de86b965801b8
--- /dev/null
+++ b/tests/unit/lib/classes/ActionMenuTest.php
@@ -0,0 +1,60 @@
+<?php
+/**
+ * @author Jan-Hendrik Willms <tleilax+studip@gmail.com>
+ * @since Stud.IP 5.4
+ */
+class ActionMenuTest extends \Codeception\Test\Unit
+{
+    public function setup(): void
+    {
+        Config::set(new Config(['ACTION_MENU_THRESHOLD' => 1]));
+    }
+
+    public function testClassShouldExist(): void
+    {
+        $this->assertTrue(class_exists(ActionMenu::class));
+    }
+
+    /**
+     * @covers ActionMenu::get
+     */
+    public function testInstanceGeneration(): void
+    {
+        $actionmenu = ActionMenu::get();
+
+        $this->assertInstanceOf(ActionMenu::class, $actionmenu);
+        $this->assertNotSame($actionmenu, ActionMenu::get());
+    }
+
+    public function testThreshold(): void
+    {
+        $actionmenu = ActionMenu::get();
+
+        $this->assertEquals(ActionMenu::RENDERING_MODE_ICONS, $actionmenu->getRenderingMode());
+
+        $actionmenu->addLink('#1', 'foo');
+        $this->assertEquals(ActionMenu::RENDERING_MODE_ICONS, $actionmenu->getRenderingMode());
+
+        $actionmenu->addLink('#2', 'bar');
+        $this->assertEquals(ActionMenu::RENDERING_MODE_MENU, $actionmenu->getRenderingMode());
+    }
+
+    /**
+     * @covers ActionMenu::setRenderingMode
+     * @covers ActionMenu::getRenderingMode
+     */
+    public function testForcingOfRenderingMode(): void
+    {
+        $actionmenu = ActionMenu::get();
+        $this->assertEquals(ActionMenu::RENDERING_MODE_ICONS, $actionmenu->getRenderingMode());
+
+        $actionmenu->setRenderingMode(ActionMenu::RENDERING_MODE_ICONS);
+        $this->assertEquals(ActionMenu::RENDERING_MODE_ICONS, $actionmenu->getRenderingMode());
+
+        $actionmenu->setRenderingMode(ActionMenu::RENDERING_MODE_MENU);
+        $this->assertEquals(ActionMenu::RENDERING_MODE_MENU, $actionmenu->getRenderingMode());
+
+        $actionmenu->setRenderingMode(null);
+        $this->assertEquals(ActionMenu::RENDERING_MODE_ICONS, $actionmenu->getRenderingMode());
+    }
+}