Unittests, Cacheobjekt, $phpbb_container

In diesem Forum gibt es Starthilfe zum neuen Extension-System von phpBB 3.1/3.2. Fragen zur Entwicklung von Extensions und zur Konvertierung von phpBB 3.0.x MODs sind ebenfalls willkommen.
Antworten
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Unittests, Cacheobjekt, $phpbb_container

Beitrag von gn#36 »

Zunächst vorweg: An der Stelle an der es gerade nicht funktioniert wäre die simple Lösung: "Wir lassen den Cache einfach weg, denn er wird eigentlich gerade eh nicht gebraucht." Aber es gibt noch andere Stellen, wo er doch nützlich wäre, für die habe ich nur gerade keinen Unit-Test.

Nehmen wir mal an, unsere Extension hat irgend ein Modul, dem ich in der services.yml ein Cache Objekt übergebe:

Code: Alles auswählen

    phpbbde.pastebin.cron.main:
        class: phpbbde\pastebin\cron\main
        arguments:
            - @cache
            - @config
            - @dbal.conn
            - @log
            - %phpbbde.pastebin.path%
            - %core.root_path%
            - %core.php_ext%
        calls:
            - [set_name, [phpbbde.pastebin.cron.main]]
        tags:
            - { name: cron.task }
Dieses Cache Objekt ist nun vom Typ phpbb\cache\service, der dementsprechend auch im Konstruktor der aufgerufenen Klasse definiert ist:

Code: Alles auswählen

public function __construct(\phpbb\cache\service $cache, \phpbb\config\config $config, \phpbb\db\driver\driver_interface $db, \phpbb\log\log_interface $log, $pastebin_path, $root_path, $php_ext)
Das bedeutet, dass ein Unittest ebenfalls ein Objekt dieses Typs braucht, um die Klasse zu testen. Interessanterweise implementiert dieses Objekt aber nicht \phpbb\cache\driver\driver_interface, weshalb man es nicht einfach durch das Mock-Objekt ersetzen kann, obwohl es dank __call sämtliche Aufrufe einfach an den Driver weiterleitet und deshalb genauso agiert wie ein Objekt dieses Typs. Das wiederum führt dazu, dass ich ein neues Objekt vom Typ \phpbb\cache\service mit Mockobjekten füttern muss, so dass ich es in den Unittests benutzen kann:

Code: Alles auswählen

$cache = new \phpbb\cache\service($this->getMock('\phpbb\cache\driver\driver_interface'), $config, $db, $phpbb_root_path, $phpEx);
Gibt's da einen einfacheren Weg? Oder gibt's statt @cache was weniger aufgeblasenes? Ich brauche ja im Prinzip eh nur die Schnittstelle von \phpbb\cache\driver\driver_interface

Dazugehöriger Travis Build: https://travis-ci.org/gn36/phpbb-ext-pa ... s/50568549
Und die entsprechende Branch: https://github.com/gn36/phpbb-ext-paste ... /dev/tests

Noch eine weitere Frage dazu: Nehmen wir mal an, ich möchte ein paar in der services.yml definierte Parameter mit einem Unittest auf ihre Gültigkeit überprüfen:

Code: Alles auswählen

parameters:
    phpbbde.pastebin.path: %core.root_path%ext/phpbbde/pastebin/
    phpbbde.pastebin.geshi: %phpbbde.pastebin.path%vendor/easybook/geshi/
    phpbbde.pastebin.geshilangs: %phpbbde.pastebin.geshi%geshi/
    phpbbde.pastebin.cron.prune_interval: 86400
    tables.phpbbde.pastebin.pastebin: %core.table_prefix%pastebin
Wie komme ich an die Parameter ran? Für den Unittest von Klassen, die darauf zugreifen habe ich die Variablen im Test neu angelegt:

Code: Alles auswählen

$phpbb_container = new \phpbb_mock_container_builder();
        $params = array(
            'phpbbde.pastebin.path'         => $phpbb_root_path . 'ext/phpbbde/pastebin/',
            'phpbbde.pastebin.geshi'         => $phpbb_root_path . 'ext/phpbbde/pastebin/' . 'vendor/easybook/geshi/',
            'phpbbde.pastebin.geshilangs'     => $phpbb_root_path . 'ext/phpbbde/pastebin/' . 'vendor/easybook/geshi/' . 'geshi/',
            'phpbbde.pastebin.cron.prune_interval' => 86400,
            'tables.phpbbde.pastebin.pastebin' => 'phpbb_pastebin',
        );
        foreach($params as $name => $value)
        {
            $phpbb_container->setParameter($name, $value);
        } 
Aber das nützt mir natürlich nichts, wenn ich überprüfen will, ob die Parameter selbst in Ordnung sind.
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Benutzeravatar
nickvergessen
Ehrenadmin
Beiträge: 11559
Registriert: 09.10.2006 21:56
Wohnort: Stuttgart, Germany
Kontaktdaten:

Re: Unittests, Cacheobjekt, $phpbb_container

Beitrag von nickvergessen »

Ich würde einfach den Service an sich schon mocken und nicht erst den driver.

Code: Alles auswählen

$this->user = $this->getMockBuilder('\phpbb\cache\service')
    ->disableOriginalConstructor()
    ->getMock();
Und dann angeben was die jeweiligen Methoden zurück geben sollen, z.B.: https://github.com/nickvergessen/phpbb- ... st.php#L41

https://github.com/gn36/phpbb-ext-paste ... in.php#L74 bitte kein global verwenden.
Auch Parameter kann man einfach injecten ;) Damit brauchst du dann auch das Object \phpbb_mock_container_builder() nicht mehr erstellen.

Bzgl Parameter testen. Vllt hilft dir da https://github.com/phpbb/phpbb/blob/dev ... r_test.php weiter.
kein Support per PN
Benutzeravatar
gn#36
Ehrenadmin
Beiträge: 9313
Registriert: 01.10.2006 16:20
Wohnort: Ganz in der Nähe...
Kontaktdaten:

Re: Unittests, Cacheobjekt, $phpbb_container

Beitrag von gn#36 »

Danke für die Rückmeldung. Ich sehe schon, ich muss da noch einiges mehr an Zeit rein investieren...
Begegnungen mit dem Chaos sind fast unvermeidlich, Aber nicht katastrophal, solange man den Durchblick behält.
Übertreiben sollte man's im Forum aber nicht mit dem Chaos, denn da sollen ja andere durchblicken und nicht nur man selbst.
Antworten

Zurück zu „Extension Bastelstube“