Ce TP vise à renforcer vos compétences dans l’écriture et l’exécution de tests unitaires avec Symfony. Il vous permettra également de pratiquer le développement piloté par les tests (TDD) pour construire un service métier. Vous couvrirez des tests sur des entités, services, contrôleurs et repositories, tout en explorant les bonnes pratiques des tests unitaires.
Vous allez construire et tester une application Symfony pour gérer un magasin en ligne. Les principales fonctionnalités incluent la gestion des clients, des produits et des commandes, ainsi que le calcul du total des commandes.
- Créer une entité
Productavec les attributs suivants :- name (string)
- price (float)
- Créer un test unitaire pour vérifier que l’entité
Productest valide.
- Créer une entité
Order - Créer une entité
OrderItem - Créer une relation entre
OrderetOrderItem- Une entité Order peut contenir plusieurs
OrderItem - Un OrderItem appartient à une seule entité
Order
- Une entité Order peut contenir plusieurs
- Créer un test unitaire pour vérifier que l’entité
Orderest valide.
- Créer le service
OrderCalculator:// src/Service/OrderCalculator.php namespace App\Service; use App\Entity\Order; class OrderCalculator { public function calculateTotal(Order $order): float { $total = 0; foreach ($order->getItems() as $item) { $total += $item->getQuantity() * $item->getUnitPrice(); } return $total; } public function applyDiscount(float $total, float $discount): float { return $total - ($total * $discount / 100); } }
- Créer un test unitaire pour vérifier que les 2 méthodes du service
OrderCalculatorsont valides.
- Créer un contrôleur
ProductControlleravec une méthode list :// src/Controller/ProductController.php #[Route('/products', name: 'product_list')] public function list(): JsonResponse { return new JsonResponse([ new Product(['name' => 'Laptop', 'price' => 1200]), new Product(['name' => 'Smartphone', 'price' => 800]), ]); }
- Créer un test unitaire pour vérifier que la méthode list du contrôleur
ProductControllerest valide.
- Créer une méthode
findExpensiveProductsdans le repositoryProductRepository:public function findExpensiveProducts(float $price): array { return $this->createQueryBuilder('p') ->where('p.price > :price') ->setParameter('price', $price) ->getQuery() ->getResult(); }
- Créer un test unitaire pour vérifier que la méthode
findExpensiveProductsdu repositoryProductRepositoryest valide.
Nous allons écrire un test pour un service StockManager qui réduit le stock d’un produit.
Le test est écrit avant même d’implémenter la méthode reduceStock.
// tests/Service/StockManagerTest.php
namespace App\Tests\Service;
use App\Entity\Product;
use App\Service\StockManager;
use PHPUnit\Framework\TestCase;
class StockManagerTest extends TestCase
{
public function testReduceStock(): void
{
$product = new Product();
$product->setName('Laptop')->setPrice(1200)->setStock(10);
$manager = new StockManager();
$manager->reduceStock($product, 2);
$this->assertEquals(8, $product->getStock());
}
public function testReduceStockWithInvalidQuantity(): void
{
$product = new Product();
$product->setName('Laptop')->setPrice(1200)->setStock(10);
$manager = new StockManager();
$this->expectException(\InvalidArgumentException::class);
$manager->reduceStock($product, 15); // Trop de stock à réduire
}
}Vous devez implémenter la classe StockManager pour que les tests passent.
