Ich habe PHPUnit Tests für meine extension mit gemockten Objekten geschrieben. Nun möchte ich mit der "realen Welt" testen.
Die Datenbankverbindung habe ich herstellen können. Damit klappen die queries.
Um Instanzen von Isotope Klassen zu bekommen - in meinem Fall einen Isotope Warenkorb und ein Item im Warenkorb - benötige ich ein Contao Framework. Und hier komme ich nicht wirklich weiter, obwohl ich versucht habe, unter den extensions weitere Beispiele zu finden und die Doku und dieses Forum und andere Foren durchsucht habe.
Zum Beispiel liefert (Code stammt von ChatGPT)
Code:// Initialisiere das reale ContaoFramework-Objekt $this->framework = System::getContainer()->get('contao.framework');Wenn ich das Framework mit new ContaoFramework() instanzieren will, muss ich ne Menge an Parametern übergeben, die sich mir nicht leicht erschließen.You have requested a non-existent service "contao.framework"
Es handelt sich um eine Extension für Isotope (nahati/contao-isotope-stock), die ich kräftig erweitert habe. Die Konfiguration habe ich aus terminal42\contao-changelanguage übernommen (bootstrap,php und die Methode, eine Erweiterung derzu bauen.PHPUnit\Framework\TestCase
Hier die relevanten (?) Dateien:
UpdateItemInCollectionListenerTest.php:
PHP-Code:
<?php
declare(strict_types=1);
namespaceNahati\ContaoIsotopeStockBundle\Tests\Integration\EventListener;
use Contao\CoreBundle\Framework\ContaoFramework;
use Contao\System;
use Isotope\Model\Product\Standard;
use Isotope\Model\ProductCollection\Cart;
use Isotope\Model\ProductCollectionItem;
use Nahati\ContaoIsotopeStockBundle\EventListener\UpdateItemInCollectionListener;
use Nahati\ContaoIsotopeStockBundle\Tests\IntegrationTestCase;
/**
* Test the UpdateItemInCollectionListener class.
*/
classUpdateItemInCollectionListenerTestextendsIntegrationTestCase
{
privateProductCollectionItem$objItem;
privateCart$objCart;
privatemixed$arrSet;
protectedContaoFramework$framework;
/**
* setup() is called for each Testcase and contains the basic setup for the tests.
* Override this method if you need to change the basic setup.
*/
protectedfunctionsetUp(): void
{
parent::setUp();
// Initialisiere das reale ContaoFramework-Objekt
// $this->framework = System::getContainer()->get('contao.framework');
}
publicfunctiontestUpdateItemInCollectionListenerReturnsQuantityZeroWhenProductIsSoldout(): void
{
$listener = newUpdateItemInCollectionListener($this->framework);
// Fetch the Cart from the test database
$this->objCart = $this->fetchCart();
// Fetch an Item of this Cart and get the product
// ... and set its inventory_status to SOLDOUT ...
$result = $listener($this->objItem, $this->arrSet, $this->objCart);
// Test if Listener returns Quantity Zero
$this->assertSame(0, $result['quantity']);
}
}
?
IntegrationTestCase.php:
PHP-Code:
<?php
declare(strict_types=1);
namespaceNahati\ContaoIsotopeStockBundle\Tests;
use Contao\CoreBundle\Framework\ContaoFramework;
use Contao\System;
use Contao\TestCase\ContaoTestCase;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Result;
use Isotope\Model\ProductCollection\Cart;
use PHPUnit\Framework\TestCase;
/*
* This class is used as a base class for all integration tests.
* It contains the basic setup for the tests.
*/
abstractclassIntegrationTestCaseextendsTestCase
{
/**
* setup() is called for each Testcase and contains the refresh of the test database.
*/
protectedConnection$db;
protectedResult$result;
protectedfunctionsetUp(): void
{
parent::setUp();
$this->db = System::getContainer()->get('database_connection');
// Drop all tables
foreach ($this->db->createSchemaManager()->listTableNames() as $table) {
$sql = 'DROP TABLE IF EXISTS '.$table;
$this->db->executeStatement($sql);
}
// Check that this->db is empty
$this->assertSame([], $this->db->createSchemaManager()->listTableNames());
// Create tables and insert data
$this->loadFixture('isotope.sql');
$queryBuilder = $this->db->createQueryBuilder();
$queryBuilder->select('*')->from('tl_iso_product');
$stm = $queryBuilder->executeQuery();
$data = $stm->fetchAllAssociative();
// Check that this->db is not empty
$this->assertNotEmpty($data);
}
publicfunctionloadFixture(string$fileName): void
{
$sql = file_get_contents(__DIR__.'/Fixtures/'.$fileName);
$this->db->executeStatement($sql);
}
publicfunctionfetchCart(): Cart
{
// return the Cart object with id 1
$queryBuilder = $this->db->createQueryBuilder();
$queryBuilder->select('*')->from('tl_iso_product_collection')->where('id = 1');
$stm = $queryBuilder->executeQuery();
$data = $stm->fetchAllAssociative();
$cart = newCart($data[0]);
return$cart;
}
}
bootstrap.php: (Die Klasse "Template" musste ich erstmal ausschließen, da sie als bereits vorhanden angemeckert wurde, warum weiß ich nicht)
PHP-Code:
<?php
declare(strict_types=1);
use Contao\CoreBundle\Config\ResourceFinder;
use Contao\System;
use Doctrine\DBAL\DriverManager;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
use Symfony\Component\HttpKernel\Log\Logger;
include_once__DIR__.'/../vendor/autoload.php';
ini_set('error_reporting', E_ALL & ~E_NOTICE);
ini_set('display_errors', true);
ini_set('display_startup_errors', true);
spl_autoload_register(
staticfunction ($class): void {
if ($class === 'Template') {
return; // Exclude the class Template
}
// TODO: Testabfrage entfernen
if (class_exists($class, false) || interface_exists($class, false) || trait_exists($class, false)) {
return;
}
if (false !== strpos($class, '\\') && false === strpos($class, 'Model\\') && false === strpos($class, 'Database\\')) {
return;
}
$namespaced = 'Contao\\'.$class;
if (class_exists($namespaced) || interface_exists($namespaced) || trait_exists($namespaced)) {
class_alias($namespaced, $class);
}
}
);
define('TL_ROOT', __DIR__.'/../');
define('TL_MODE', '');
define('TL_ERROR', 'error');
define('BE_USER_LOGGED_IN', false);
$container = newContainerBuilder(
newParameterBag(
[
'kernel.debug' => false,
'kernel.cache_dir' => sys_get_temp_dir(),
'kernel.bundles' => ['ContaoIsotopeStockBundle'],
]
)
);
$container->setParameter('kernel.project_dir', __DIR__.'/../');
$container->set('contao.resource_locator', newFileLocator([__DIR__.'/../contao']));
$container->set('contao.resource_finder', newResourceFinder([__DIR__.'/../contao/']));
$container->set('monolog.logger.contao', newLogger());
$container->set('database_connection', DriverManager::getConnection([
'driver' => 'pdo_mysql',
'url' => $_ENV['DATABASE_URL'],
]));
System::setContainer($container);
phpunit.xml.dist:
PHP-Code:
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/10.1/phpunit.xsd"
colors="true"
bootstrap="tests/bootstrap.php"
failOnRisky="true"
failOnWarning="false">
<coverage
includeUncoveredFiles="true"
pathCoverage="true"
ignoreDeprecatedCodeUnits="true"
disableCodeCoverageIgnore="true">
<report>
<html
outputDirectory="html-coverage"
lowUpperBound="50"
highLowerBound="90" />
<text
outputFile="coverage.txt"
showUncoveredFiles="false"
showOnlySummary="true" />
</report>
</coverage>
<php>
<ini
name="error_reporting"
value="-1" />
<server
name="APP_ENV"
value="test" />
<env
name="SYMFONY_DEPRECATIONS_HELPER"
value="weak" />
<env
name="DATABASE_URL"
value="mysql://root:@127.0.0.1:3306/ContaoIsotopeStockBundleTest" />
</php>
<testsuites>
<testsuite name="integration">
<directory>./tests/integration</directory>
</testsuite>
</testsuites>
</phpunit>
Lesezeichen