Tipos de retorno nulo / sub-rotinas são notícias antigas. Não faço um tipo de retorno nulo (a menos que eu esteja sendo extremamente preguiçoso) há 8 anos (desde o momento desta resposta, um pouco antes da pergunta).
Em vez de um método como:
public void SendEmailToCustomer()
Crie um método que siga o paradigma int.TryParse () da Microsoft:
public bool TrySendEmailToCustomer()
Talvez não exista nenhuma informação que seu método precise retornar para uso a longo prazo, mas retornar o estado do método depois que ele executa seu trabalho é uma grande utilidade para o chamador.
Além disso, bool não é o único tipo de estado. Há várias vezes em que uma sub-rotina feita anteriormente pode realmente retornar três ou mais estados diferentes (bom, normal, ruim etc.). Nesses casos, você usaria apenas
public StateEnum TrySendEmailToCustomer()
No entanto, embora o Try-Paradigm responda de alguma forma a essa pergunta sobre como testar um retorno nulo, há outras considerações também. Por exemplo, durante / após um ciclo "TDD", você estaria "Refatorando" e notaria que está fazendo duas coisas com seu método ... quebrando, assim, o "Princípio de responsabilidade única". Portanto, isso deve ser tratado primeiro. Segundo, você pode ter identificado uma dependência ... está tocando em Dados "persistentes".
Se você estiver executando o material de acesso a dados no método em questão, precisará refatorar para uma arquitetura de camada n ou camada. Mas podemos assumir que quando você diz "As cadeias são inseridas em um banco de dados", na verdade quer dizer que está chamando uma camada de lógica de negócios ou algo assim. Sim, vamos assumir isso.
Quando seu objeto é instanciado, agora você entende que ele possui dependências. É quando você precisa decidir se fará Injeção de Dependência no Objeto ou no Método. Isso significa que seu construtor ou o método em questão precisa de um novo parâmetro:
public <Constructor/MethodName> (IBusinessDataEtc otherLayerOrTierObject, string[] stuffToInsert)
Agora que você pode aceitar uma interface do seu objeto de camada de negócios / dados, pode simulá-la durante testes de unidade e não tem dependências ou medo de testes de integração "acidentais".
Então, no seu código ativo, você passa um IBusinessDataEtc
objeto REAL . Mas em seu teste de unidade, você passa um IBusinessDataEtc
objeto MOCK . Nesse Mock, você pode incluir as propriedades que não são da interface, int XMethodWasCalledCount
ou algo cujos estados são atualizados quando os métodos da interface são chamados.
Portanto, seu teste de unidade passará por seu (s) método (s) em questão, execute qualquer lógica que ele tenha e chame um ou dois ou um conjunto selecionado de métodos em seu IBusinessDataEtc
objeto. Quando você faz suas afirmações no final do seu teste de unidade, você tem algumas coisas para testar agora.
- O estado da "sub-rotina", que agora é um método Try-Paradigm.
- O estado do seu
IBusinessDataEtc
objeto simulado .
Para obter mais informações sobre as idéias de injeção de dependência no nível da construção ... no que se refere ao teste de unidade ... consulte os padrões de design do Builder. Ele adiciona mais uma interface e classe para cada interface / classe atual que você possui, mas elas são muito pequenas e fornecem enormes aumentos de funcionalidade para um melhor teste de unidade.