Quando a propriedade é definida no banco de dados de produção (ou em um clone para teste), este não é um teste de unidade . Um teste de unidade verifica uma unidade de trabalho e não requer um estado externo específico para funcionar. Isso pressupõe que Offer1
está definido no banco de dados como uma oferta apenas para homens. Esse é o estado externo. Portanto, este é mais um teste de integração , especificamente um sistema ou teste de aceitação . Observe que os testes de aceitação geralmente não são com script (não são executados em uma estrutura de teste, mas são executados manualmente por seres humanos).
Quando a propriedade é definida no modelo de domínio com uma if
instrução, o mesmo teste é um teste de unidade. E pode ser quebradiço. Mas o verdadeiro problema é que o código é quebradiço. Como regra geral, seu código será mais resiliente se o comportamento dos negócios for configurável em vez de codificado. Porque uma implantação rápida para corrigir um pequeno erro de codificação deve ser rara. Mas um requisito comercial que muda sem aviso prévio é apenas uma terça-feira (algo que acontece semanalmente).
Você pode estar usando uma estrutura de teste de unidade para executar o teste. Mas as estruturas de teste de unidade não se limitam à execução de testes de unidade. Eles também podem executar testes de integração.
Se você estivesse escrevendo um teste de unidade, criaria ambos person
e offer1
desde o início, sem depender do estado do banco de dados. Algo como
[Fact]
public void ReturnsFalseWhenGivenAPersonWithAGenderOfFemale()
{
var personId = Guid.NewGuid();
var gender = "F";
var person = new Person(personId, gender);
var id = Guid.NewGuid();
var offer1 = new Offer1(id, "ReturnsFalseWhenGivenAPersonWithAGenderOfFemale");
offer1.markLimitedToGender("M");
Assert.False(offer1.IsEligible(person));
}
Observe que isso não muda com base na lógica de negócios. Não é afirmar que offer1
rejeita mulheres. Está fazendo offer1
o tipo de oferta que rejeita mulheres.
Você pode criar e configurar o banco de dados como parte do teste. No C #, usando NUnit, ou no JUnit de Java, você configuraria o banco de dados em um Setup
método. Presumivelmente, sua estrutura de teste tem uma noção semelhante. Nesse método, você pode inserir registros no banco de dados com SQL.
Se for difícil escrever código que substitua um banco de dados de teste pelo banco de dados de produção, isso soa como uma fraqueza de teste no seu aplicativo. Para o teste, seria melhor usar algo como injeção de dependência que permita a substituição. Em seguida, você pode escrever testes independentes das regras de negócios atuais.
Um benefício colateral disso é que muitas vezes é mais fácil para o proprietário da empresa (não necessariamente o proprietário da empresa, mais parecido com a pessoa responsável por este produto na hierarquia corporativa) configurar as regras de negócios diretamente. Como se você possui esse tipo de estrutura técnica, é fácil permitir que o proprietário da empresa use uma interface de usuário (UI) para configurar a oferta. O proprietário da empresa selecionaria a limitação na interface do usuário e emitia a markLimitedToGender("M")
chamada. Então, quando a oferta persistir no banco de dados, ela será armazenada. Mas você não precisaria armazenar a oferta para usá-la. Portanto, seus testes podem criar e configurar uma oferta que não existe no banco de dados.
No sistema, conforme descrito, o proprietário da empresa precisaria fazer uma solicitação ao grupo técnico, que emitisse o SQL apropriado e atualizaria os testes. Ou o grupo técnico precisa editar seu código e testes (ou testes e depois código). Essa parece uma abordagem bastante pesada. Você consegue. Mas o seu software (não apenas o seu teste) seria menos quebradiço se você não precisasse fazer isso.
TL; DR : você pode escrever testes como este, mas é melhor escrever seu software para não precisar fazer isso.