diff --git a/lib/private/command/queuebus.php b/lib/private/command/queuebus.php
new file mode 100644
index 0000000000000000000000000000000000000000..29c769e01075ed74f03588d265e2fbf466cc5277
--- /dev/null
+++ b/lib/private/command/queuebus.php
@@ -0,0 +1,53 @@
+<?php
+/**
+ * Copyright (c) 2015 Robin Appelman <icewind@owncloud.com>
+ * This file is licensed under the Affero General Public License version 3 or
+ * later.
+ * See the COPYING-README file.
+ */
+
+namespace OC\Command;
+
+use OCP\Command\IBus;
+use OCP\Command\ICommand;
+
+class QueueBus implements IBus {
+	/**
+	 * @var (ICommand|callable)[]
+	 */
+	private $queue;
+
+	/**
+	 * Schedule a command to be fired
+	 *
+	 * @param \OCP\Command\ICommand | callable $command
+	 */
+	public function push($command) {
+		$this->queue[] = $command;
+	}
+
+	/**
+	 * Require all commands using a trait to be run synchronous
+	 *
+	 * @param string $trait
+	 */
+	public function requireSync($trait) {
+	}
+
+	/**
+	 * @param \OCP\Command\ICommand | callable $command
+	 */
+	private function runCommand($command) {
+		if ($command instanceof ICommand) {
+			$command->handle();
+		} else {
+			$command();
+		}
+	}
+
+	public function run() {
+		while ($command = array_shift($this->queue)) {
+			$this->runCommand($command);
+		}
+	}
+}
diff --git a/tests/lib/testcase.php b/tests/lib/testcase.php
index 1ea3aa135479ef6f0de1c17979471124558124fc..2b4540120d253daacca43ad1d13505385c9dcba3 100644
--- a/tests/lib/testcase.php
+++ b/tests/lib/testcase.php
@@ -22,9 +22,23 @@
 
 namespace Test;
 
+use OC\Command\QueueBus;
 use OCP\Security\ISecureRandom;
 
 abstract class TestCase extends \PHPUnit_Framework_TestCase {
+	/**
+	 * @var \OC\Command\QueueBus
+	 */
+	private $commandBus;
+
+	protected function setUp() {
+		// overwrite the command bus with one we can run ourselves
+		$this->commandBus = new QueueBus();
+		\OC::$server->registerService('AsyncCommandBus', function(){
+			return $this->commandBus;
+		});
+	}
+
 	/**
 	 * Returns a unique identifier as uniqid() is not reliable sometimes
 	 *
@@ -55,6 +69,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
 
 	/**
 	 * Remove all entries from the files map table
+	 *
 	 * @param string $dataDir
 	 */
 	static protected function tearDownAfterClassCleanFileMapper($dataDir) {
@@ -66,6 +81,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
 
 	/**
 	 * Remove all entries from the storages table
+	 *
 	 * @throws \OC\DatabaseException
 	 */
 	static protected function tearDownAfterClassCleanStorages() {
@@ -76,6 +92,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
 
 	/**
 	 * Remove all entries from the filecache table
+	 *
 	 * @throws \OC\DatabaseException
 	 */
 	static protected function tearDownAfterClassCleanFileCache() {
@@ -91,11 +108,11 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
 	 */
 	static protected function tearDownAfterClassCleanStrayDataFiles($dataDir) {
 		$knownEntries = array(
-			'owncloud.log'	=> true,
-			'owncloud.db'	=> true,
-			'.ocdata'		=> true,
-			'..'			=> true,
-			'.'				=> true,
+			'owncloud.log' => true,
+			'owncloud.db' => true,
+			'.ocdata' => true,
+			'..' => true,
+			'.' => true,
 		);
 
 		if ($dh = opendir($dataDir)) {
@@ -122,8 +139,7 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
 				$path = $dir . '/' . $file;
 				if (is_dir($path)) {
 					self::tearDownAfterClassCleanStrayDataUnlinkDir($path);
-				}
-				else {
+				} else {
 					@unlink($path);
 				}
 			}
@@ -169,4 +185,11 @@ abstract class TestCase extends \PHPUnit_Framework_TestCase {
 		\OC_Util::tearDownFS();
 		\OC_User::setUserId('');
 	}
+
+	/**
+	 * Run all commands pushed to the bus
+	 */
+	protected function runCommands() {
+		$this->commandBus->run();
+	}
 }