Solucionado (ver solução)
Solucionado
(ver solução)
2
respostas

Testes com repositórios em memória

Fala mestre, beleza?

Você deu a dica para criar repositórios em memória para realizar testes de unidade, seria um dublê do tipo fake, eu acho. Os testes de unidades que dependem do nosso repositório não poderiam ser um stub, especificando apenas o que os métodos irão retornar?

Uma outra dúvida é em relação aos testes para o método encontrarTodos() :

Nesse teste eu preciso de além de verificar a quantidade e tipo de registros retornados, verificar também se são realmente os mesmos registros inseridos. Só a título de exemplo:

public function testVerificaSeOsAlunosESeusRespectivosTelefonesEstaoArmazenados()
{
    $alunos = $this->repositorio->encontreTodos();

    $this->assertCount(3, $alunos);
    $this->assertContainsOnlyInstancesOf(Aluno::class, $alunos);

    $this->assertSame('Rodrigo',  $alunos[0]->nome());
    $this->assertSame('89293943829',  $alunos[0]->telefones()[0]);
    //etc..
}

O problema é que ao não usar qualquer banco que esteja em memória a ordem dos alunos retornados do método encontreTodos() não é a mesma ordem que foram inseridos. Ou seja, quando eu faço: $alunos[0]->nome() eu não sei quem é esse aluno, logo não posso comparar com algo. Uma solução óbvia é que após chamar o método encontreTodos() eu faça uma transformação no array para inserir em suas chaves os cpfs dos alunos. É errado fazer esse tipo de coisa? Quebra algum padrão? Ficando assim:

public function testVerificaSeOsAlunosESeusRespectivosTelefonesEstaoArmazenados()
{

    $alunos = $this->insiraCpfComoChave($this->repositorio->encontreTodos());

    $this->assertCount(3, $alunos);
    $this->assertContainsOnlyInstancesOf(Aluno::class, $alunos);

    $this->assertSame('Rodrigo',  $alunos['738.928.293-32']->nome());
    $this->assertSame('89293943829',  $alunos['738.928.293-32']->telefones()[0]);
    //etc..
}
2 respostas
solução!

seria um dublê do tipo fake, eu acho

Exato!

Os testes de unidades que dependem do nosso repositório não poderiam ser um stub, especificando apenas o que os métodos irão retornar?

Podem sim. É uma possibilidade. A ideia de usar um Fake é chegar um pouquinho mais próximo da realidade além de não depender de uma ferramenta que cria dublês, mas na prática, as vantagens são pouquíssimas. A ideia do desafio é mais exercitar a ideia de que podemos ter várias implementações de uma interface mesmo. :-)

É errado fazer esse tipo de coisa? Quebra algum padrão?

Não é errado não, Diego, mas seu teste deve ser executado em um ambiente controlado, então você deve sim saber qual o primeiro aluno. Usando um banco relacional, por exemplo, o primeiro aluno retornado vai ser o primeiro aluno inserido, caso não haja regra específica de ordenação. ;-)

Eu esqueci da regra padrão de ordenação do MySQL que é de acordo com as chaves primárias. O "encontreTodos()" resgata do banco os alunos na ordem ascendente dos CPF.

deve ser executado em um ambiente controlado É isso, estava achando estranho ter que usar de um artifício para saber quem é quem na busca, não me atentei ao detalhe da ordenação padrão do banco, inicialmente parecia que os dados vinham embaralhados, mas sempre seguem alguma ordem =D.