User Tools

Site Tools


programmieren:testing:unittest:controller_tests

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Next revision
Previous revision
programmieren:testing:unittest:controller_tests [2026/08/25 16:17] – created adminprogrammieren:testing:unittest:controller_tests [2026/09/09 09:39] (current) – actually show controller tests admin
Line 9: Line 9:
   * Preparing session data by getting that certain entry from the test database   * Preparing session data by getting that certain entry from the test database
   * Adding the whole user entity we got in the previous step to the session with an "Auth" prefix   * Adding the whole user entity we got in the previous step to the session with an "Auth" prefix
 +
 +Kinda looks like this:
 +<code php>
 +[
 +    // Superuser
 +    'id' => 'dd137c92-9f03-4f0d-8e9a-0fba608ed373',
 +    'username' => 'superadmin',
 +    'password' => '$2y$10$tJek1ncybnTlHjEeyFh22umgK9c145mI5t8nMd05WIakA3CtsvTCu',
 +    'active' => 1,
 +    'is_superuser' => 1,
 +    'created' => '2026-08-25 11:21:37',
 +    'modified' => '2026-08-25 11:21:37',
 +],
 +</code>
 +
 +<code php>
 +protected function getSuperuserSessionData(): Entity
 +{
 +    /** @var UsersTable $usersTable */
 +    $usersTable = $this->getTableLocator()->get('Users');
 +
 +    $sessionData = $usersTable->find()->where(['id' => '<id of the user entry>'])->first();
 +
 +    return $sessionData;
 +}
 +</code>
 +
 +<code php>
 +protected function loginAs($sessionData): void
 +{
 +    if (!method_exists($this, 'session')) {
 +        throw new RuntimeException('No session component available');
 +    }
 +
 +    $this->session([
 +        'Auth' => $sessionData,
 +    ]);
 +}
 +</code>
  
 Only then can you request the controller like normal. Only then can you request the controller like normal.
  
 When controller actions include saving things, it makes sense to compare the expected value to the view variable and to the value that was saved to the database. When controller actions include saving things, it makes sense to compare the expected value to the view variable and to the value that was saved to the database.
 +
 +This would kinda look like this for an index endpoint for accounts table:
 +
 +<code php>
 +public function testIndex(): void
 +{
 + $accountsTable = $this->getTableLocator()->get('Accounts');
 + $accountCount = $accountsTable->find()->count();
 +
 + $this->loginAsSuperuser();
 +
 + $this->get('/accounts');
 +
 + $this->assertResponseOk();
 +
 + $accounts = $this->viewVariable('accounts')->toArray();
 +
 + $account = simplifyDateTimesInArray($accounts[0]->toArray());
 +
 + self::assertCount($accountCount, $accounts);
 + self::assertEquals([
 + 'id' => 1,
 + 'uuid' => '9841e242-4ad6-43e7-842c-aeb392a0f862',
 + 'created' => '2025-11-24 14:56:09.000000 CET',
 + 'modified' => '2025-11-24 14:56:09.000000 CET',
 + 'customer_id' => 1,
 + 'name' => 'OSe',
 + 'email' => 'isp@orca-services.ch',
 + 'company' => 'ORCA Services AG (interne Projekte)',
 + 'currency' => 'CHF',
 + 'customer' => [
 + 'id' => 1,
 + 'name' => 'OSe',
 + ],
 + ], $account);
 + self::assertNull($accounts[1]->customer);
 +}
 +</code>
 +
 +Notice the ''customer'' which is an associated table, whose name and id get loaded with the account, this is necessary to be able to show in the UI which customer an account belongs to.
 +
 +This is what the same looks like for an add post endpoint
 +
 +<code php>
 +public function testAddPost(): void
 +{
 + $accountsTable = $this->getTableLocator()->get('Accounts');
 + $data = [
 + 'customer_id' => '1',
 + 'uuid' => '1251e242-4ad6-43e7-842c-aeb392a0f862',
 + 'name' => 'TestAccount',
 + 'email' => 'test@account.ch',
 + 'company' => 'Test Account AG',
 + 'currency' => 'CHF',
 + ];
 +
 + $this->enableCsrfToken();
 + $this->loginAsSuperuser();
 +
 + $this->post('/accounts/add', $data);
 +
 + $this->assertResponseCode(HttpStatuses::STATUS_FOUND);
 +
 + /** @var Account $account */
 + $account = $accountsTable->find()->orderByDesc('id')->first();
 +
 + self::assertEquals('1251e242-4ad6-43e7-842c-aeb392a0f862', $account->uuid);
 + self::assertEquals('1', $account->customer_id);
 +}
 +</code>
 +
 +Here you just test if the entry you added actually corresponds to the data that was input.
 +
 +And this is what a delete endpoint test looks like
 +
 +<code php>
 +public function testDelete(): void
 +{
 + $id = 1;
 + $accountsTable = $this->getTableLocator()->get('Accounts');
 +
 + /** @var Account $account */
 + $account = $accountsTable->find()->where(['id' => $id])->first();
 + self::assertNotNull($account);
 +
 + $this->enableCsrfToken();
 + $this->loginAsSuperuser();
 +
 + $this->post('/accounts/delete/' . $id);
 +
 + $this->assertResponseCode(HttpStatuses::STATUS_FOUND);
 + $this->assertRedirect('/');
 +
 + /** @var Account $account */
 + $account = $accountsTable->find()->where(['id' => $id])->first();
 + self::assertNull($account);
 +}
 +</code>
 +
 +Here you test beforehand if the entry with the selected ID exists (it should), then you call the delete endpoint and check the entry again, now it shouldnt exist.
 +
 +For all endpoints you also check if it correctly redirects you (if it should do that).
 +
 +You also check every endpoint as unauthenticated (unless it should be available as unauthenticated) and check if it correctly redirects to the login.
programmieren/testing/unittest/controller_tests.1787667474.txt.gz · Last modified: by admin

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki