/** * Execute database query * * @param string $sql Query * @param array $params Query params * @return PHPUnit_Framework_MockObject_MockObject (statement) */ public function executeDatabaseQuery($sql, $params = []) { $sql = $this->normalizeSql($sql); $results = []; $row_count = 0; $this->last_insert_id = null; $match = false; foreach ($this->query_specs as $i => $spec) { if ($spec->sql == $sql && $params == $spec->params) { $match = true; if (isset($spec->results)) { if (is_callable($spec->results)) { $results = call_user_func($spec->results, $spec); } else { if (is_array($spec->results)) { $results = $spec->results; } } } $row_count = isset($spec->row_count) ? $spec->row_count : count($results); if (isset($spec->insert_id)) { $this->last_insert_id = $spec->insert_id; } if (isset($spec->remaining)) { $spec->remaining--; if (!$spec->remaining) { // don't allow more matches unset($this->query_specs[$i]); } } break; } } if (!$match && strpos($sql, 'select') !== 0) { // We need to make sure all UPDATE, INSERT and DELETE queries are // mocked, otherwise we will be getting incorrect test results throw new \DatabaseException("No testing query spec was found"); } $statement = $this->test->getMockBuilder(\Doctrine\DBAL\PDOStatement::class)->setMethods(['fetch', 'rowCount'])->disableOriginalConstructor()->getMock(); $statement->expects($this->test->any())->method('fetch')->will($this->test->returnCallback(function () use(&$results) { return array_shift($results); })); $statement->expects($this->test->any())->method('rowCount')->will($this->test->returnValue($row_count)); return $statement; }