[PHP] Request mocken

Pagina: 1
Acties:

Vraag


  • ZeroXT
  • Registratie: December 2007
  • Nu online
Ik probeer een request te mocken maar begrijp nog niet goed wat de beste manier is.

Er is een Authentication class die een Config object met daarin de client id en secret als constructor parameter ontvangt. In deze Authentication class zit een method genaamd obtainToken die een POST request uitvoert met de opgegeven Config credentials en een Token object retourneert.

Nu wil ik dit unit testen, maar wil ik niet daadwerkelijk de POST request uitvoeren, maar in plaats daarvan deze mocken.

Dit is hoe de unit test eruit zonder mock:
PHP:
1
2
3
4
5
6
7
$config = new AuthConfig('id', 'secret');
$authentication = new Authentication($config);
$token = $authentication->obtainToken();

$this->assertIsInt($token->getExpiration());
$this->assertEquals('bearer', $token->getType());
$this->assertIsString($token->getAccessToken());


Nu probeer ik met Mockery de request te mocken. Let hierbij op dat deze code niet werkt omdat $token geen Token object is, omdat ik nog niet uit ben hoe dit werkt.

PHP:
1
2
3
4
5
6
7
$config = new AuthConfig('id', 'secret');
$authentication = Mockery::mock(Authentication::class);
$token = $authentication->shouldReceive('obtainToken')->andReturn(Token::fromArray(['access_token' => 'token', 'expires_in' => 1000, 'token_type' => 'bearer']));

$this->assertIsInt($token->getExpiration());
$this->assertEquals('bearer', $token->getType());
$this->assertIsString($token->getAccessToken());


Vragen:
- Wat is nog de toegevoegde waarde is van het config object aangezien deze niet meer gebruikt wordt?
- In dit geval geef ik zelf een Token object terug dus wat is nog toegevoegde waarde van het mocken van de Authentication class?
- Zijn er nog tips en tricks om deze test beter te maken?


Als referentie de Authentication class:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
class Authentication
{
    private AuthConfigInterface $config;
    private ClientInterface $client;

    public function __construct(AuthConfigInterface $config)
    {
        $this->client = new Client();
        $this->config = $config;
    }

    public function obtainToken(): Token
    {
        try {
            $response = $this->client->request('POST', $this->config->getAuthenticationUrl(), [
                'form_params' => [
                    'client_id' => $this->config->getClientId(),
                    'client_secret' => $this->config->getClientSecret(),
                    'grant_type' => 'client_credentials',
                ],
            ]);
        }
        catch (ClientExceptionInterface $exception) {
            throw AuthenticationException::authenticationFailed('Failed to successfully authenticate.', $exception);
        }

        $tokenData = json_decode($response->getBody()->getContents(), true, 512, JSON_THROW_ON_ERROR);
        return Token::fromArray($tokenData);
    }
}

Alle reacties


  • Kalentum
  • Registratie: Juni 2004
  • Nu online
Wat ik zou doen: de 'Client' mocken. Maar dan moet je ook je constructor aanpassen zodat een Client object en een Config object nodig heeft.

Nou weet ik niet of je test voor de Authentication class is of voor iets anders. Als het de Authentication Class is die onder test is dan moet je niet obtainToken mocken maar de Client, namelijk de ->request method.

Want in de huidige setup met mocken van obtainToken heb je de aanroep van getClientId en getClientSecret en de grant type niet meer meer onder test. Als ik getClientID wijzig in getFoo() dan breekt de test niet.

Acties:
  • 0 Henk 'm!

  • Matis
  • Registratie: Januari 2007
  • Laatst online: 11:55

Matis

Rubber Rocket

Je moet je bij het schrijven van een test afvragen wát je wilt testen. Mijn inziens zijn er drie typen tests:
  • Unit
  • Integration
  • End-2-end
Wat probeer je hier te testen? En in welke van de drie vormen wil je dit testen?

If money talks then I'm a mime
If time is money then I'm out of time