connection = new PdoConnection($config); try { $this->connection->pdo(); } catch (MyException $e) { $this->markTestSkipped('Нет живого подключения к MariaDB (заполните App/config/config.local.php): ' . $e->getMessage()); } $this->connection->exec('DROP TABLE IF EXISTS repository_test_items'); $this->connection->exec('CREATE TABLE repository_test_items (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255), qty INT)'); $this->repository = new RepositoryTestItemRepository(); } protected function tearDown(): void { Profiler::reset(); if (isset($this->connection)) { try { $this->connection->exec('DROP TABLE IF EXISTS repository_test_items'); } catch (MyException) { } } // Database::instance() кэширует подключение статически — сбрасываем между тестами $ref = new ReflectionClass(Database::class); $prop = $ref->getProperty('_instances'); $prop->setAccessible(true); $prop->setValue(null, []); } public function testCreateAndGet(): void { $id = $this->repository->create(['name' => 'foo', 'qty' => 3]); $row = $this->repository->get($id); $this->assertSame('foo', $row->name); $this->assertSame(3, (int) $row->qty); } public function testGetMissingReturnsFalse(): void { $this->assertFalse($this->repository->get(999999)); } public function testGetListWithWhere(): void { $this->repository->create(['name' => 'a', 'qty' => 1]); $this->repository->create(['name' => 'b', 'qty' => 2]); $this->repository->create(['name' => 'a', 'qty' => 5]); $rows = $this->repository->getList('*', ['name' => 'a'], '', 'ASC', PDO::FETCH_ASSOC); $this->assertCount(2, $rows); } public function testGetItemWhere(): void { $this->repository->create(['name' => 'foo', 'qty' => 1]); $row = $this->repository->getItemWhere("name = 'foo'"); $this->assertSame('foo', $row->name); } public function testGetItemWhereEmptyReturnsNull(): void { $this->assertNull($this->repository->getItemWhere('')); } public function testUpdate(): void { $id = $this->repository->create(['name' => 'foo', 'qty' => 1]); $affected = $this->repository->update(['id' => $id, 'qty' => 10]); $this->assertSame(1, $affected); $this->assertSame(10, (int) $this->repository->get($id)->qty); } public function testUpdateWithoutPrimaryKeyThrows(): void { $this->expectException(MyException::class); $this->repository->update(['qty' => 10]); } public function testDelete(): void { $id = $this->repository->create(['name' => 'foo', 'qty' => 1]); $this->assertTrue($this->repository->delete($id)); $this->assertFalse($this->repository->get($id)); } public function testDeleteWhere(): void { $this->repository->create(['name' => 'a', 'qty' => 1]); $this->repository->create(['name' => 'a', 'qty' => 2]); $this->repository->create(['name' => 'b', 'qty' => 3]); $this->repository->deleteWhere('name = ?', ['a']); $this->assertCount(1, $this->repository->getList('*', [], '', 'ASC', PDO::FETCH_ASSOC)); } public function testTransactionRollsBackOnException(): void { try { $this->repository->transaction(function () { $this->repository->create(['name' => 'should_rollback', 'qty' => 1]); throw new \RuntimeException('boom'); }); $this->fail('Ожидалось RuntimeException'); } catch (\RuntimeException) { } $this->assertCount(0, $this->repository->getList('*', ['name' => 'should_rollback'], '', 'ASC', PDO::FETCH_ASSOC)); } public function testGetListFetchAssoc(): void { $this->repository->create(['name' => 'foo', 'qty' => 1]); $rows = $this->repository->getList('*', [], '', 'ASC', PDO::FETCH_ASSOC); $this->assertIsArray($rows[0]); $this->assertSame('foo', $rows[0]['name']); } public function testGetListDefaultFetchClassUsesObjClass(): void { // По умолчанию (без явного $fetch) getList() отдаёт $this->obj_class — не generic stdClass. $this->repository->create(['name' => 'foo', 'qty' => 1]); $rows = $this->repository->getList('*'); $this->assertInstanceOf(\Services\DataBase\Model::class, $rows[0]); $this->assertSame('foo', $rows[0]->name); } }