Pergunta

Então, estou trabalhando em algum código legado que envolve muitas operações manuais de banco de dados.Estou tentando manter alguma aparência de qualidade aqui, então vou usar o TDD o máximo possível.

O código em que estou trabalhando precisa ser preenchido, digamos, um List<Foo> de um DataReader que retorna todos os campos necessários para um Foo funcional.No entanto, se eu quiser verificar se o código de fato retorna um item de lista por linha do banco de dados, estou escrevendo um código de teste semelhante a este:

Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 1);
// ....
Expect.Call(reader.Read()).Return(true);
Expect.Call(reader["foo_id"]).Return((long) 2);
// ....
Expect.Call(reader.Read()).Return(false);

O que é bastante tedioso e facilmente quebrado também.

Como devo abordar esse problema para que o resultado não seja uma grande confusão de testes frágeis?

A propósito, atualmente estou usando o Rhino.Mocks para isso, mas posso alterá-lo se o resultado for convincente o suficiente.Contanto que a alternativa não seja TypeMock, porque o EULA deles era um pouco assustador para o meu gosto da última vez que verifiquei.

Editar:Atualmente também estou limitado ao C# 2.

Foi útil?

Solução

Para tornar isso menos tedioso, você precisará encapsular/refatorar o mapeamento entre o DataReader e o Objeto que você mantém na lista.Existem algumas etapas para encapsular essa lógica.Se esse for o caminho que você deseja seguir, posso postar o código para você.Só não tenho certeza de quão prático seria postar o código aqui no StackOverflow, mas posso tentar mantê-lo conciso e direto ao ponto.Caso contrário, você ficará preso à tediosa tarefa de repetir cada expectativa no acessador de índice para o leitor.O processo de encapsulamento também eliminará as strings e as tornará mais reutilizáveis ​​por meio de seus testes.

Além disso, não tenho certeza neste momento do quanto você deseja tornar o código existente mais testável.Uma vez que este é um código legado que não foi criado com o teste em mente.

Outras dicas

Pensei em postar algum código e então me lembrei do curso Nothin But .NET do JP Boodhoo.Ele tem um projeto de amostra que ele está compartilhando que foi criado durante uma de suas aulas.O projeto está hospedado em Código do Google e é um bom recurso.Tenho certeza de que contém algumas dicas interessantes para você usar e dar ideias sobre como refatorar o mapeamento.Todo o projeto foi construído com TDD.

Você pode colocar as instâncias de Foo em uma lista e comparar os objetos com o que você lê:

var arrFoos = new Foos[]{...}; // what you expect
var expectedFoos = new List<Foo>(arrFoos); // make a list from the hardcoded array of expected Foos
var readerResult = ReadEntireList(reader); // read everything from reader and put in List<Foo>
Expect.ContainSameFoos(expectedFoos, readerResult); // compare the two lists

Kokos,

Algumas coisas erradas aí.Primeiro, fazer dessa forma significa que primeiro tenho que construir os Foos e, em seguida, alimentar seus valores para o leitor simulado, que não faz nada para reduzir a quantidade de código que estou escrevendo.Segundo, se os valores passarem pelo leitor, os Foos não serão os mesmo Foos (igualdade de referência).Eles podem ser igual, mas mesmo isso pressupõe muito da classe Foo que não me atrevo a tocar neste momento.

Só para esclarecer, você deseja testar sua chamada no SQL Server retornando alguns dados ou que, se você tivesse alguns dados, poderia mapeá-los de volta para o modelo?

Se você quiser testar sua chamada no SQL retornou alguns dados, minha resposta foi encontrada aqui

@Toran:O que estou testando é o mapeamento programático dos dados retornados do banco de dados para o modelo de domínio entre aspas.Por isso, quero zombar da conexão com o banco de dados.Para o outro tipo de teste, eu optaria por testes de integração completos.

@Dale:Acho que você acertou em cheio e fiquei com medo de que fosse esse o caso.Se você tiver alguma indicação de algum artigo ou algo parecido em que alguém tenha feito o trabalho sujo e o decomposto em etapas mais facilmente digeríveis, eu agradeceria.Amostras de código também não fariam mal.Eu tenho uma ideia de como abordar esse problema, mas antes de realmente ousar fazer isso, precisarei fazer outras coisas e, se o teste exigir uma simulação tediosa, então é isso que farei.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top