Maison  >  Article  >  développement back-end  >  Problèmes courants et solutions dans la pratique des tests unitaires PHP

Problèmes courants et solutions dans la pratique des tests unitaires PHP

PHPz
PHPzoriginal
2024-05-06 12:42:011158parcourir

Problèmes courants avec les tests unitaires PHP : Tests de dépendances externes : utilisation d'un framework moqueur (tel que Mockery) pour créer de fausses dépendances et affirmer leurs interactions. Tests de membres privés : utilisez des API de réflexion telles que ReflectionMethod pour accéder aux membres privés ou utilisez des modificateurs de visibilité de test tels que @protected. Tests d'interaction de base de données : configurez et vérifiez l'état de la base de données à l'aide d'un cadre de test de base de données tel que DbUnit. Tests d'API/service Web externes : utilisez une bibliothèque client HTTP pour simuler les interactions, à l'aide d'un serveur local ou stub dans l'environnement de test.

PHP 单元测试实践中的常见问题与解决方案

Questions fréquemment posées sur les tests unitaires PHP

Question 1 : Comment tester unitairement du code avec des dépendances externes ?

Solution : Utilisez un framework moqueur comme Mockery ou Prophecy de PHPUnit qui vous permet de créer de faux objets de dépendance et de faire des assertions sur leurs interactions.

use Prophecy\Prophet;

class UserRepoTest extends \PHPUnit\Framework\TestCase
{
    public function testFetchUser(): void
    {
        $prophet = new Prophet();
        $cache = $prophet->prophesize(Cache::class);

        $userRepo = new UserRepo($cache->reveal());

        $actualUser = $userRepo->fetchUser(1);

        $cache->get(1)->shouldHaveBeenCalled();
        $this->assertEquals($expectedUser, $actualUser);
    }
}

Question 2 : Comment tester une méthode ou une propriété privée ?

Solution : Utilisez des API de réflexion (telles que ReflectionClass et ReflectionMethod) qui vous permettent d'accéder aux membres privés. Cependant, cela peut rendre les tests difficiles à maintenir. ReflectionClassReflectionMethod),允许你访问私有成员。然而,它可能会使测试难以维护。

另一种解决方案是使用测试特定的可见性修饰符,例如 PHPUnit 的 @protected

Une autre solution consiste à utiliser un modificateur de visibilité spécifique au test, tel que @protected de PHPUnit.

class UserTest extends \PHPUnit\Framework\TestCase
{
    public function testPasswordIsSet(): void
    {
        $user = new User();

        $reflector = new ReflectionClass($user);
        $property = $reflector->getProperty('password');

        $property->setAccessible(true);
        $property->setValue($user, 'secret');

        $this->assertEquals('secret', $user->getPassword());
    }
}
Question 3 : Comment tester l'interaction avec la base de données ?

Solution :

Utilisez un framework de test de base de données tel que DbUnit de PHPUnit ou Doctrine DBAL Assertions qui vous permet de définir et de vérifier l'état de la base de données.

use PHPUnit\DbUnit\TestCase;

class PostRepoTest extends TestCase
{
    protected function getConnection(): Connection
    {
        return $this->createDefaultDBConnection();
    }

    public function testCreatePost(): void
    {
        $dataset = $this->createXMLDataSet(__DIR__ . '/initial-dataset.xml');
        $this->getDatabaseTester()->setDataSet($dataset);
        $this->getDatabaseTester()->onSetUp();

        $post = new Post(['title' => 'My First Post']);
        $postRepo->persist($post);
        $postRepo->flush();

        $this->assertTrue($this->getConnection()->getRowCount('posts') === 1);
    }
}
Question 4 : Comment tester du code qui s'appuie sur des API ou des services web externes ?

Solution :

Utilisez une bibliothèque client HTTP pour simuler les interactions avec des services externes. Dans un environnement de test, vous pouvez utiliser un serveur local ou stub. 🎜
use GuzzleHttp\Client;

class UserServiceTest extends \PHPUnit\Framework\TestCase
{
    public function testFetchUser(): void
    {
        $httpClient = new Client();
        $userService = new UserService($httpClient);

        $httpClient
            ->shouldReceive('get')
            ->with('/users/1')
            ->andReturn(new Response(200, [], json_encode(['id' => 1, 'name' => 'John Doe'])));

        $user = $userService->fetchUser(1);

        $this->assertInstanceOf(User::class, $user);
        $this->assertEquals(1, $user->getId());
    }
}

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn