From 0e22c18a9da7b1a55e188964af84886bfa7aae32 Mon Sep 17 00:00:00 2001
From: Philipp Holzer <admin@philipp.info>
Date: Wed, 31 Oct 2018 10:16:15 +0100
Subject: [PATCH] Bugfixing & Enhancement

- Added Mocking Engine for App, DBA, Config
- Using Mocking Engine for AutomaticInstallationConsoleTest
- Using Mocking Engine for ConfigConsoleTest

- Removing MultiUserConsole - Workaround
---
 tests/Util/AppMockTrait.php                   |  90 ++++++++++
 tests/Util/ConfigMockTrait.php                |  59 +++++++
 tests/Util/DBAMockTrait.php                   |  35 ++++
 tests/Util/DBStructureMockTrait.php           |  37 ++++
 tests/datasets/ini/assert.ini.php             |  56 ++++++
 tests/datasets/ini/assert_db.ini.php          |  56 ++++++
 .../AutomaticInstallationConsoleTest.php      | 165 ++++++++++--------
 tests/src/Core/Console/ConfigConsoleTest.php  | 106 +++++++----
 tests/src/Core/Console/ConsoleTest.php        |  63 +++----
 tests/src/Core/Console/MultiUseConsole.php    |  23 ---
 10 files changed, 515 insertions(+), 175 deletions(-)
 create mode 100644 tests/Util/AppMockTrait.php
 create mode 100644 tests/Util/ConfigMockTrait.php
 create mode 100644 tests/Util/DBAMockTrait.php
 create mode 100644 tests/Util/DBStructureMockTrait.php
 create mode 100644 tests/datasets/ini/assert.ini.php
 create mode 100644 tests/datasets/ini/assert_db.ini.php
 delete mode 100644 tests/src/Core/Console/MultiUseConsole.php

diff --git a/tests/Util/AppMockTrait.php b/tests/Util/AppMockTrait.php
new file mode 100644
index 0000000000..c04b5d7dc5
--- /dev/null
+++ b/tests/Util/AppMockTrait.php
@@ -0,0 +1,90 @@
+<?php
+
+namespace Friendica\Test\Util;
+
+use Friendica\App;
+use Friendica\BaseObject;
+use Friendica\Render\FriendicaSmartyEngine;
+use org\bovigo\vfs\vfsStreamDirectory;
+
+/**
+ * Trait to Mock the global App instance
+ */
+trait AppMockTrait
+{
+	use ConfigMockTrait;
+	use DBAMockTrait;
+
+	/**
+	 * @var App The Friendica global App Mock
+	 */
+	protected $app;
+
+	/**
+	 * Mock the App
+	 *
+	 * @param vfsStreamDirectory $root The root directory
+	 */
+	public function mockApp($root)
+	{
+		/// @todo This mock is ugly. We return an empty string for each translation - no workaround yet
+		$l10nMock = \Mockery::mock('alias:Friendica\Core\L10n');
+		$l10nMock->shouldReceive('t')
+			->andReturn('');
+
+		$this->mockConfigGet('system', 'theme', 'testtheme');
+
+		// Mocking App and most used functions
+		$this->app = \Mockery::mock('Friendica\App');
+		$this->app
+			->shouldReceive('getBasePath')
+			->andReturn($root->url());
+
+		$this->app
+			->shouldReceive('getConfigValue')
+			->with('database', 'hostname')
+			->andReturn(getenv('MYSQL_HOST'));
+		$this->app
+			->shouldReceive('getConfigValue')
+			->with('database', 'username')
+			->andReturn(getenv('MYSQL_USERNAME'));
+		$this->app
+			->shouldReceive('getConfigValue')
+			->with('database', 'password')
+			->andReturn(getenv('MYSQL_PASSWORD'));
+		$this->app
+			->shouldReceive('getConfigValue')
+			->with('database', 'database')
+			->andReturn(getenv('MYSQL_DATABASE'));
+		$this->app
+			->shouldReceive('getTemplateEngine')
+			->andReturn(new FriendicaSmartyEngine());
+		$this->app
+			->shouldReceive('getCurrentTheme')
+			->andReturn('Smarty3');
+		$this->app
+			->shouldReceive('getTemplateLeftDelimiter')
+			->with('smarty3')
+			->andReturn('{{');
+		$this->app
+			->shouldReceive('getTemplateRightDelimiter')
+			->with('smarty3')
+			->andReturn('}}');
+		$this->app
+			->shouldReceive('saveTimestamp')
+			->andReturn(true);
+		$this->app
+			->shouldReceive('getBaseUrl')
+			->andReturn('http://friendica.local');
+
+		// Mocking the Theme
+		// Necessary for macro engine with template files
+		$themeMock = \Mockery::mock('alias:Friendica\Core\Theme');
+		$themeMock
+			->shouldReceive('install')
+			->with('testtheme')
+			->andReturn(true);
+
+		BaseObject::setApp($this->app);
+	}
+}
diff --git a/tests/Util/ConfigMockTrait.php b/tests/Util/ConfigMockTrait.php
new file mode 100644
index 0000000000..8e285f3922
--- /dev/null
+++ b/tests/Util/ConfigMockTrait.php
@@ -0,0 +1,59 @@
+<?php
+
+namespace Friendica\Test\Util;
+
+/**
+ * Trait to Mock Config settings
+ */
+trait ConfigMockTrait
+{
+	private $configMock;
+
+	/**
+	 * Mocking a config setting
+	 *
+	 * @param string $family The family of the config double
+	 * @param string $key The key of the config double
+	 * @param mixed $value The value of the config double
+	 * @param null|int $times How often the Config will get used
+	 */
+	public function mockConfigGet($family, $key, $value, $times = null)
+	{
+		if (!isset($this->configMock)) {
+			$this->configMock = \Mockery::mock('alias:Friendica\Core\Config');
+		}
+
+		$this->configMock
+			->shouldReceive('get')
+			->times($times)
+			->with($family, $key)
+			->andReturn($value);
+	}
+
+	/**
+	 * Mocking setting a new config entry
+	 *
+	 * @param string $family The family of the config double
+	 * @param string $key The key of the config double
+	 * @param mixed $value The value of the config double
+	 * @param null|int $times How often the Config will get used
+	 * @param bool $return Return value of the set (default is true)
+	 */
+	public function mockConfigSet($family, $key, $value, $times = null, $return = true)
+	{
+		if (!isset($this->configMock)) {
+			$this->configMock = \Mockery::mock('alias:Friendica\Core\Config');
+		}
+
+		$this->mockConfigGet($family, $key, false, 1);
+		if ($return) {
+			$this->mockConfigGet($family, $key, $value, 1);
+		}
+
+		$this->configMock
+			->shouldReceive('set')
+			->times($times)
+			->with($family, $key, $value)
+			->andReturn($return);
+	}
+}
diff --git a/tests/Util/DBAMockTrait.php b/tests/Util/DBAMockTrait.php
new file mode 100644
index 0000000000..77746f7d9e
--- /dev/null
+++ b/tests/Util/DBAMockTrait.php
@@ -0,0 +1,35 @@
+<?php
+
+namespace Friendica\Test\Util;
+
+/**
+ * Trait to mock the DBA connection status
+ */
+trait DBAMockTrait
+{
+	private $dbaMock;
+
+	public function mockConnect($return = true, $times = null)
+	{
+		if (!isset($this->dbaMock)) {
+			$this->dbaMock = \Mockery::mock('alias:Friendica\Database\DBA');
+		}
+
+		$this->dbaMock
+			->shouldReceive('connect')
+			->times($times)
+			->andReturn($return);
+	}
+
+	public function mockConnected($return = true, $times = null)
+	{
+		if (!isset($this->dbaMock)) {
+			$this->dbaMock = \Mockery::mock('alias:Friendica\Database\DBA');
+		}
+
+		$this->dbaMock
+			->shouldReceive('connected')
+			->times($times)
+			->andReturn($return);
+	}
+}
diff --git a/tests/Util/DBStructureMockTrait.php b/tests/Util/DBStructureMockTrait.php
new file mode 100644
index 0000000000..3298107eb3
--- /dev/null
+++ b/tests/Util/DBStructureMockTrait.php
@@ -0,0 +1,37 @@
+<?php
+
+namespace Friendica\Test\Util;
+
+/**
+ * Trait to mock the DBStructure connection status
+ */
+trait DBStructureMockTrait
+{
+	private $dbStructure;
+
+	public function mockUpdate($args = [], $return = true, $times = null)
+	{
+		if (!isset($this->dbStructure)) {
+			$this->dbStructure = \Mockery::mock('alias:Friendica\Database\DBStructure');
+		}
+
+		$this->dbStructure
+			->shouldReceive('update')
+			->withArgs($args)
+			->times($times)
+			->andReturn($return);
+	}
+
+	public function mockExistsTable($tableName, $return = true, $times = null)
+	{
+		if (!isset($this->dbStructure)) {
+			$this->dbStructure = \Mockery::mock('alias:Friendica\Database\DBStructure');
+		}
+
+		$this->dbStructure
+			->shouldReceive('existsTable')
+			->with($tableName)
+			->times($times)
+			->andReturn($return);
+	}
+}
diff --git a/tests/datasets/ini/assert.ini.php b/tests/datasets/ini/assert.ini.php
new file mode 100644
index 0000000000..39828affcb
--- /dev/null
+++ b/tests/datasets/ini/assert.ini.php
@@ -0,0 +1,56 @@
+<?php return <<<INI
+
+; If you're unsure about what any of the config keys below do, please check the config/defaults.ini.php for detailed
+; documentation of their data type and behavior.
+
+[database]
+hostname = ""
+username = ""
+password = ""
+database = ""
+charset = utf8mb4
+
+; ****************************************************************
+; Some config values below can be overruled from the admin settings
+; ****************************************************************
+
+[config]
+php_path = "/usr/bin/php"
+
+admin_email = "admin@friendica.local"
+
+sitename = Friendica Social Network
+
+register_policy = REGISTER_OPEN
+register_text =
+
+max_import_size = 200000
+
+[system]
+urlpath = "/friendica"
+
+default_timezone = "Europe/Berlin"
+
+language = "de"
+
+allowed_themes = vier,quattro,duepuntozero,smoothly,frio
+theme = vier
+
+allowed_link_protocols[0] = ftp
+allowed_link_protocols[1] = ftps
+allowed_link_protocols[2] = mailto
+allowed_link_protocols[3] = cid
+allowed_link_protocols[4] = gopher
+
+maximagesize = 800000
+
+no_regfullname = true
+
+block_local_dir = false
+
+directory = https://dir.friendica.social
+
+auth_cookie_lifetime = 7
+
+INI;
+// Keep this line
\ No newline at end of file
diff --git a/tests/datasets/ini/assert_db.ini.php b/tests/datasets/ini/assert_db.ini.php
new file mode 100644
index 0000000000..f42c9ddba2
--- /dev/null
+++ b/tests/datasets/ini/assert_db.ini.php
@@ -0,0 +1,56 @@
+<?php return <<<INI
+
+; If you're unsure about what any of the config keys below do, please check the config/defaults.ini.php for detailed
+; documentation of their data type and behavior.
+
+[database]
+hostname = "localhost:3306"
+username = "friendica"
+password = "friendica"
+database = "friendica"
+charset = utf8mb4
+
+; ****************************************************************
+; Some config values below can be overruled from the admin settings
+; ****************************************************************
+
+[config]
+php_path = "/usr/bin/php"
+
+admin_email = "admin@friendica.local"
+
+sitename = Friendica Social Network
+
+register_policy = REGISTER_OPEN
+register_text =
+
+max_import_size = 200000
+
+[system]
+urlpath = "/friendica"
+
+default_timezone = "Europe/Berlin"
+
+language = "de"
+
+allowed_themes = vier,quattro,duepuntozero,smoothly,frio
+theme = vier
+
+allowed_link_protocols[0] = ftp
+allowed_link_protocols[1] = ftps
+allowed_link_protocols[2] = mailto
+allowed_link_protocols[3] = cid
+allowed_link_protocols[4] = gopher
+
+maximagesize = 800000
+
+no_regfullname = true
+
+block_local_dir = false
+
+directory = https://dir.friendica.social
+
+auth_cookie_lifetime = 7
+
+INI;
+// Keep this line
\ No newline at end of file
diff --git a/tests/src/Core/Console/AutomaticInstallationConsoleTest.php b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
index 4e1f269dcd..78f4e14e91 100644
--- a/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
+++ b/tests/src/Core/Console/AutomaticInstallationConsoleTest.php
@@ -2,6 +2,8 @@
 
 namespace Friendica\Test\src\Core\Console;
 
+use Friendica\Core\Console\AutomaticInstallation;
+use Friendica\Test\Util\DBStructureMockTrait;
 use org\bovigo\vfs\vfsStream;
 
 /**
@@ -11,12 +13,17 @@ use org\bovigo\vfs\vfsStream;
  */
 class AutomaticInstallationConsoleTest extends ConsoleTest
 {
+	use DBStructureMockTrait;
+
 	private $db_host;
 	private $db_port;
 	private $db_data;
 	private $db_user;
 	private $db_pass;
 
+	private $assertFile;
+	private $assertFileDb;
+
 	public function setUp()
 	{
 		parent::setUp();
@@ -32,19 +39,20 @@ class AutomaticInstallationConsoleTest extends ConsoleTest
 		$this->db_user = getenv('MYSQL_USERNAME') . getenv('MYSQL_USER');
 		$this->db_pass = getenv('MYSQL_PASSWORD');
 
-		// Mocking 'DBStructure::existsTable()' because with CI, we cannot create an empty database
-		// therefore we temporary override the existing database
-		/// @todo Mocking the DB-Calls of ConsoleTest so we don't need this specific mock anymore
-		$existsMock = \Mockery::mock('alias:Friendica\Database\DBStructure');
-		$existsMock->shouldReceive('existsTable')
-			->with('user')
-			->andReturn(false);
-	}
+		$this->mockConfigGet('config', 'php_path', false);
 
-	private function assertConfig($family, $key, $value)
-	{
-		$config = $this->execute(['config', $family, $key]);
-		$this->assertEquals($family . "." . $key . " => " . $value . "\n", $config);
+		$this->assertFile  = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+			'..' . DIRECTORY_SEPARATOR .
+			'..' . DIRECTORY_SEPARATOR .
+			'datasets' . DIRECTORY_SEPARATOR .
+			'ini' . DIRECTORY_SEPARATOR .
+			'assert.ini.php';
+		$this->assertFileDb  = dirname(__DIR__) . DIRECTORY_SEPARATOR .
+			'..' . DIRECTORY_SEPARATOR .
+			'..' . DIRECTORY_SEPARATOR .
+			'datasets' . DIRECTORY_SEPARATOR .
+			'ini' . DIRECTORY_SEPARATOR .
+			'assert_db.ini.php';
 	}
 
 	private function assertFinished($txt, $withconfig = false, $copyfile = false)
@@ -113,14 +121,17 @@ FIN;
 		$finished = <<<FIN
 Initializing setup...
 
-Creating config file...
+ Complete!
+
+
+Checking environment...
+
+ NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
 
  Complete!
 
 
-Checking basic setup...
-
- NOTICE: Not checking .htaccess/URL-Rewrite during CLI installation.
+Creating config file...
 
  Complete!
 
@@ -128,7 +139,7 @@ Checking basic setup...
 Checking database...
 
 [Error] --------
-MySQL Connection: Failed, please check your MySQL settings and credentials.
+: 
 
 
 FIN;
@@ -141,6 +152,11 @@ FIN;
 	 */
 	public function testWithConfig()
 	{
+		$this->mockConnect(true, 1);
+		$this->mockConnected(true, 1);
+		$this->mockExistsTable('user', false, 1);
+		$this->mockUpdate([false, true, true], null, 1);
+
 		$config = <<<CONF
 <?php return <<<INI
 
@@ -179,7 +195,10 @@ CONF;
 			->at($this->root)
 			->setContent($config);
 
-		$txt = $this->execute(['autoinstall', '-f', 'prepared.ini.php']);
+		$console = new AutomaticInstallation();
+		$console->setOption('f', 'prepared.ini.php');
+
+		$txt = $this->dumpExecute($console);
 
 		$this->assertFinished($txt, false, true);
 
@@ -191,23 +210,28 @@ CONF;
 	 */
 	public function testWithEnvironmentAndSave()
 	{
+		$this->mockConnect(true, 1);
+		$this->mockConnected(true, 1);
+		$this->mockExistsTable('user', false, 1);
+		$this->mockUpdate([false, true, true], null, 1);
+
 		$this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
 		$this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
 		$this->assertTrue(putenv('FRIENDICA_LANG=de'));
+		$this->assertTrue(putenv('FRIENDICA_URL_PATH=/friendica'));
 
-		$txt = $this->execute(['autoinstall', '--savedb']);
+		$console = new AutomaticInstallation();
+		$console->setOption('savedb', true);
+
+		$txt = $this->dumpExecute($console);
 
 		$this->assertFinished($txt, true);
 
 		$this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
 
-		$this->assertConfig('database', 'hostname', $this->db_host . (!empty($this->db_port) ? ':' . $this->db_port : ''));
-		$this->assertConfig('database', 'username', $this->db_user);
-		$this->assertConfig('database', 'database', $this->db_data);
-		$this->assertConfig('config', 'admin_email', 'admin@friendica.local');
-		$this->assertConfig('system', 'default_timezone', 'Europe/Berlin');
-		// TODO language changes back to en
-		//$this->assertConfig('system', 'language', 'de');
+		$this->assertFileEquals(
+			$this->assertFileDb,
+			$this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')->url());
 	}
 
 	/**
@@ -215,25 +239,27 @@ CONF;
 	 */
 	public function testWithEnvironmentWithoutSave()
 	{
+		$this->mockConnect(true, 1);
+		$this->mockConnected(true, 1);
+		$this->mockExistsTable('user', false, 1);
+		$this->mockUpdate([false, true, true], null, 1);
+
 		$this->assertTrue(putenv('FRIENDICA_ADMIN_MAIL=admin@friendica.local'));
 		$this->assertTrue(putenv('FRIENDICA_TZ=Europe/Berlin'));
 		$this->assertTrue(putenv('FRIENDICA_LANG=de'));
 		$this->assertTrue(putenv('FRIENDICA_URL_PATH=/friendica'));
 
-		$txt = $this->execute(['autoinstall']);
+		$console = new AutomaticInstallation();
 
-		$this->assertFinished($txt, true);
+		$returnStr = $this->dumpExecute($console);
+
+		$this->assertFinished($returnStr, true);
 
 		$this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
 
-		$this->assertConfig('database', 'hostname', '');
-		$this->assertConfig('database', 'username', '');
-		$this->assertConfig('database', 'database', '');
-		$this->assertConfig('config', 'admin_email', 'admin@friendica.local');
-		$this->assertConfig('system', 'default_timezone', 'Europe/Berlin');
-		$this->assertConfig('system', 'urlpath', '/friendica');
-		// TODO language changes back to en
-		//$this->assertConfig('system', 'language', 'de');
+		$this->assertFileEquals(
+			$this->assertFile,
+			$this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')->url());
 	}
 
 	/**
@@ -241,46 +267,38 @@ CONF;
 	 */
 	public function testWithArguments()
 	{
-		$args = ['autoinstall'];
-		array_push($args, '--dbhost');
-		array_push($args, $this->db_host);
-		array_push($args, '--dbuser');
-		array_push($args, $this->db_user);
+		$this->mockConnect(true, 1);
+		$this->mockConnected(true, 1);
+		$this->mockExistsTable('user', false, 1);
+		$this->mockUpdate([false, true, true], null, 1);
+
+		$console = new AutomaticInstallation();
+
+		$console->setOption('dbhost', $this->db_host);
+		$console->setOption('dbuser', $this->db_user);
 		if (!empty($this->db_pass)) {
-			array_push($args, '--dbpass');
-			array_push($args, $this->db_pass);
+			$console->setOption('dbpass', $this->db_pass);
 		}
 		if (!empty($this->db_port)) {
-			array_push($args, '--dbport');
-			array_push($args, $this->db_port);
+			$console->setOption('dbport', $this->db_port);
 		}
-		array_push($args, '--dbdata');
-		array_push($args, $this->db_data);
+		$console->setOption('dbdata', $this->db_data);
 
-		array_push($args, '--admin');
-		array_push($args, 'admin@friendica.local');
-		array_push($args, '--tz');
-		array_push($args, 'Europe/Berlin');
-		array_push($args, '--lang');
-		array_push($args, 'de');
+		$console->setOption('admin', 'admin@friendica.local');
+		$console->setOption('tz', 'Europe/Berlin');
+		$console->setOption('lang', 'de');
 
-		array_push($args, '--urlpath');
-		array_push($args, '/friendica');
+		$console->setOption('urlpath', '/friendica');
 
-		$txt = $this->execute($args);
+		$returnStr = $this->dumpExecute($console);
 
-		$this->assertFinished($txt, true);
+		$this->assertFinished($returnStr, true);
 
 		$this->assertTrue($this->root->hasChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php'));
 
-		$this->assertConfig('database', 'hostname', $this->db_host . (!empty($this->db_port) ? ':' . $this->db_port : ''));
-		$this->assertConfig('database', 'username', $this->db_user);
-		$this->assertConfig('database', 'database', $this->db_data);
-		$this->assertConfig('config', 'admin_email', 'admin@friendica.local');
-		$this->assertConfig('system', 'default_timezone', 'Europe/Berlin');
-		$this->assertConfig('system', 'urlpath', '/friendica');
-		// TODO language changes back to en
-		//$this->assertConfig('system', 'language', 'de');
+		$this->assertFileEquals(
+			$this->assertFileDb,
+			$this->root->getChild('config' . DIRECTORY_SEPARATOR . 'local.ini.php')->url());
 	}
 
 	/**
@@ -289,17 +307,13 @@ CONF;
 	 */
 	public function testNoDatabaseConnection()
 	{
-		// TODO DBA mocking for whole console tests make this test work again
-		$this->markTestSkipped('DBA is already loaded, we have to mock the whole App to make it work');
+		$this->mockConnect(false, 1);
 
-		$dbaMock = \Mockery::mock('alias:Friendica\Database\DBA');
-		$dbaMock
-			->shouldReceive('connected')
-			->andReturn(false);
+		$console = new AutomaticInstallation();
 
-		$txt = $this->execute(['autoinstall']);
+		$returnStr = $this->dumpExecute($console);
 
-		$this->assertStuckDB($txt);
+		$this->assertStuckDB($returnStr);
 	}
 
 	public function testGetHelp()
@@ -357,7 +371,10 @@ Examples
 
 HELP;
 
-		$txt = $this->execute(['autoinstall', '-h']);
+		$console = new AutomaticInstallation();
+		$console->setOption('help', true);
+
+		$txt = $this->dumpExecute($console);
 
 		$this->assertEquals($txt, $theHelp);
 	}
diff --git a/tests/src/Core/Console/ConfigConsoleTest.php b/tests/src/Core/Console/ConfigConsoleTest.php
index c4fd217770..683c7a2e37 100644
--- a/tests/src/Core/Console/ConfigConsoleTest.php
+++ b/tests/src/Core/Console/ConfigConsoleTest.php
@@ -2,7 +2,8 @@
 
 namespace Friendica\Test\src\Core\Console;
 
-use Friendica\Database\DBA;
+use Friendica\Core\Console\Config;
+use \Mockery as m;
 
 /**
  * @runTestsInSeparateProcesses
@@ -11,76 +12,105 @@ use Friendica\Database\DBA;
  */
 class ConfigConsoleTest extends ConsoleTest
 {
-	public function tearDown()
+	protected function setUp()
 	{
-		DBA::delete('config', ['k' => 'test']);
+		parent::setUp();
 
-		parent::tearDown();
-	}
+		m::getConfiguration()->setConstantsMap([
+			'Friendica\App\Mode' => [
+				'DBCONFIGAVAILABLE' => 0
+			]
+		]);
 
-	private function assertGet($family, $key, $value) {
-		$config = $this->execute(['config', $family, $key]);
-		$this->assertEquals($family . "." . $key . " => " . $value . "\n", $config);
-	}
+		$mode = m::mock('alias:Friendica\App\Mode');
+		$mode
+			->shouldReceive('has')
+			->andReturn(true);
 
-	private function assertSet($family, $key, $value) {
-		$config = $this->execute(['config', $family, $key, $value]);
-		$this->assertEquals($family . "." . $key . " <= " . $value . "\n", $config);
+		$this->app
+			->shouldReceive('getMode')
+			->andReturn($mode);
 	}
 
 	function testSetGetKeyValue() {
-		$this->assertSet( 'config', 'test', 'now');
-		$this->assertGet('config', 'test', 'now');
-		$this->assertSet('config', 'test', '');
-		$this->assertGet('config', 'test', '');
-		DBA::delete('config', ['k' => 'test']);
-		$this->assertGet('config', 'test', null);
+		$this->mockConfigSet('config', 'test', 'now', 1);
+		$console = new Config();
+		$console->setArgument(0, 'config');
+		$console->setArgument(1, 'test');
+		$console->setArgument(2, 'now');
+		$txt = $this->dumpExecute($console);
+		$this->assertEquals("config.test <= now\n", $txt);
+
+		$this->mockConfigGet('config', 'test', 'now', 1);
+		$console = new Config();
+		$console->setArgument(0, 'config');
+		$console->setArgument(1, 'test');
+		$txt = $this->dumpExecute($console);
+		$this->assertEquals("config.test => now\n", $txt);
+
+		$this->mockConfigGet('config', 'test', null, 1);
+		$console = new Config();
+		$console->setArgument(0, 'config');
+		$console->setArgument(1, 'test');
+		$txt = $this->dumpExecute($console);
+		$this->assertEquals("config.test => \n", $txt);
 	}
 
 	function testSetArrayValue() {
 		$testArray = [1, 2, 3];
-		DBA::insert('config', ['cat' => 'config', 'k' => 'test', 'v' => serialize($testArray)]);
+		$this->mockConfigGet('config', 'test', $testArray, 1);
 
-		$txt = $this->execute(['config', 'config', 'test', 'now']);
+		$console = new Config();
+		$console->setArgument(0, 'config');
+		$console->setArgument(1, 'test');
+		$console->setArgument(2, 'now');
+		$txt = $this->dumpExecute($console);
 
 		$this->assertEquals("[Error] config.test is an array and can't be set using this command.\n", $txt);
 	}
 
 	function testTooManyArguments() {
-		$txt = $this->execute(['config', 'config', 'test', 'it', 'now']);
+		$console = new Config();
+		$console->setArgument(0, 'config');
+		$console->setArgument(1, 'test');
+		$console->setArgument(2, 'it');
+		$console->setArgument(3, 'now');
+		$txt = $this->dumpExecute($console);
 		$assertion = '[Warning] Too many arguments';
 		$firstline = substr($txt, 0, strlen($assertion));
-
 		$this->assertEquals($assertion, $firstline);
 	}
 
 	function testVerbose() {
-		$this->assertSet('test', 'it', 'now');
-		$executable = $this->getExecutablePath();
+		$this->mockConfigGet('test', 'it', 'now', 1);
+		$console = new Config();
+		$console->setArgument(0, 'test');
+		$console->setArgument(1, 'it');
+		$console->setOption('v', 1);
 		$assertion = <<<CONF
-Executable: {$executable}
-Arguments: array (
-  0 => 'config',
-  1 => 'test',
-)
-Options: array (
-  'v' => 1,
-)
-Command: config
-Executable: {$executable}
+Executable: -
 Class: Friendica\Core\Console\Config
 Arguments: array (
   0 => 'test',
+  1 => 'it',
 )
 Options: array (
   'v' => 1,
 )
-[test]
-it => now
+test.it => now
 
 CONF;
-		$txt = $this->execute(['config', 'test', '-v']);
-
+		$txt = $this->dumpExecute($console);
 		$this->assertEquals($assertion, $txt);
 	}
+
+	function testUnableToSet() {
+		$this->mockConfigSet('test', 'it', 'now', 1, false);
+		$console = new Config();
+		$console->setArgument(0, 'test');
+		$console->setArgument(1, 'it');
+		$console->setArgument(2, 'now');
+		$txt = $this->dumpExecute($console);
+		$this->assertSame("Unable to set test.it\n", $txt);
+	}
 }
diff --git a/tests/src/Core/Console/ConsoleTest.php b/tests/src/Core/Console/ConsoleTest.php
index 75f339e8f5..6b58ccced2 100644
--- a/tests/src/Core/Console/ConsoleTest.php
+++ b/tests/src/Core/Console/ConsoleTest.php
@@ -2,27 +2,16 @@
 
 namespace Friendica\Test\src\Core\Console;
 
-use Friendica\App;
-use Friendica\BaseObject;
-use Friendica\Database\DBA;
+use Asika\SimpleConsole\Console;
+use Friendica\Test\Util\AppMockTrait;
 use Friendica\Test\Util\Intercept;
 use Friendica\Test\Util\VFSTrait;
-use org\bovigo\vfs\vfsStream;
-use org\bovigo\vfs\vfsStreamDirectory;
 use PHPUnit\Framework\TestCase;
 
 abstract class ConsoleTest extends TestCase
 {
 	use VFSTrait;
-
-	/**
-	 * @var MultiUseConsole Extension of the basic Friendica Console for testing purpose
-	 */
-	private $console;
-	/**
-	 * @var App The Friendica App
-	 */
-	protected $app;
+	use AppMockTrait;
 
 	protected $stdout;
 
@@ -30,43 +19,37 @@ abstract class ConsoleTest extends TestCase
 	{
 		parent::setUp();
 
-		Intercept::setUp();
-
 		if (!getenv('MYSQL_DATABASE')) {
 			$this->markTestSkipped('Please set the MYSQL_* environment variables to your test database credentials.');
 		}
 
+		Intercept::setUp();
+
 		$this->setUpVfsDir();
-
-		// fake console.php for setting an executable
-		vfsStream::newFile('console.php')
-			->at($this->root->getChild('bin'))
-			->setContent('<? php');
-
-		// Reusable App object
-		$this->app = new App($this->root->url());
-		BaseObject::setApp($this->app);
-		$this->console = new MultiUseConsole();
+		$this->mockApp($this->root);
 	}
 
-	public function execute($args) {
-		$this->app->reload();
+	protected function tearDown()
+	{
+		\Mockery::close();
 
-		array_unshift($args, $this->getExecutablePath());
-		Intercept::reset();
-		$this->console->reset();
-		$this->console->parseTestArgv($args);
-		$this->console->execute();
-
-		$returnStr = Intercept::$cache;
-		Intercept::reset();
-		return $returnStr;
+		parent::tearDown();
 	}
 
 	/**
-	 * @return string returns the path to the console executable during tests
+	 * Dumps the execution of an console output to a string and returns it
+	 *
+	 * @param Console $console The current console instance
+	 *
+	 * @return string the output of the execution
 	 */
-	protected function getExecutablePath() {
-		return $this->root->getChild('bin' . DIRECTORY_SEPARATOR . 'console.php')->url();
+	protected function dumpExecute($console)
+	{
+		Intercept::reset();
+		$console->execute();
+		$returnStr = Intercept::$cache;
+		Intercept::reset();
+
+		return $returnStr;
 	}
 }
diff --git a/tests/src/Core/Console/MultiUseConsole.php b/tests/src/Core/Console/MultiUseConsole.php
deleted file mode 100644
index ddcbfebc34..0000000000
--- a/tests/src/Core/Console/MultiUseConsole.php
+++ /dev/null
@@ -1,23 +0,0 @@
-<?php
-
-namespace Friendica\Test\src\Core\Console;
-
-use Friendica\Core\Console;
-
-/**
- * Adds two methods to the Friendica\Core\Console so we can reuse it during tests
- *
- * @package Friendica\Test\src\Core\Console
- */
-class MultiUseConsole extends Console
-{
-	public function reset() {
-		$this->args = [];
-		$this->options = [];
-	}
-
-	public function parseTestArgv($argv)
-	{
-		$this->parseArgv($argv);
-	}
-}