1
resposta

[Dúvida] Método withConsecutive()

Boa tarde! Atualmente fazendo o curso de testes, neste caso "Testes de integração com PHP: testando o acesso à API e ao banco de dados", utilizo o PHP 8.3 e PHPUnit 10.3.0 by Sebastian Bergmann and contributors, com estas versões o método withConsecutive() não é suportado, desta forma utilizei da seguinte forma a função abaixo:

ao invés de utilizar:

 $leilaoDao->expects($this->exactly(2))
     ->method('atualiza')
     ->withConsecutive(
         [$this->leilaoFiat147],
         [$this->leilaoVariante]
     );

utilizo abaixo:

$invokedCount = $this->exactly(2);
$leilaoDao->expects($invokedCount)
    ->method('atualiza')
    ->willReturnCallback(function (Leilao $leilao) { //->willReturnCallback(function (Leilao $leilao) use ($fiat147, $variant) {
        static $invocationCount = 0;
        $invocationCount++;

        if ($invocationCount === 1) {
            $this->assertSame($this->leilaoFiat147, $leilao);
        } elseif ($invocationCount === 2) {
            $this->assertSame($this->leilaoVariante, $leilao);
        }

        return null;
    });

quero saber se este meu código está correto ou se tem outra forma melhor de trocar o método withConsecutive()?

1 resposta

Oi Rafael! Boa noite!

Sim, sua solução está correta e é uma alternativa válida ao withConsecutive(), especialmente considerando a incompatibilidade com PHPUnit 10.3.0, que removeu ou limitou suporte a alguns métodos mais antigos.

A abordagem que você usou com willReturnCallback e o uso de static $invocationCount funciona bem para verificar a ordem e os argumentos passados nas chamadas ao método mockado. É uma forma manual, mas eficaz, de simular o comportamento de withConsecutive().

Só um ajuste opcional (melhoria de clareza):

Você pode declarar os objetos esperados como variáveis locais e usá-los dentro do callback, em vez de acessar diretamente propriedades da classe. Isso torna o teste mais claro e menos dependente do estado externo: $fiat147 = $this->leilaoFiat147; $variant = $this->leilaoVariante;

$leilaoDao->expects($this->exactly(2)) ->method('atualiza') ->willReturnCallback(function (Leilao $leilao) use ($fiat147, $variant) { static $invocationCount = 0; $invocationCount++;

    if ($invocationCount === 1) {
        $this->assertSame($fiat147, $leilao);
    } elseif ($invocationCount === 2) {
        $this->assertSame($variant, $leilao);
    }

    return null;
}); 

Alternativa:

Se quiser manter os testes mais simples e menos manuais, pode considerar quebrar o teste em dois, validando as chamadas individualmente com expects($this->once()) e o uso de diferentes mocks mas no seu caso, sua abordagem atual está bem estruturada e cumpre o objetivo do withConsecutive().

Parabéns pela adaptação, ficou ótimo!