Dando sequência ao post anterior vamos iniciar os testes de validação das nossas entidades com base nas especificações de Alunos e Matriculas.
Passo 13 - Abra o arquivo AlunoTests.cs no projeto de testes. Na barra de menu do Visual Studio clique em TEST -> RUN -> ALL TESTS. A imagem abaixo mostra o resultado na guia Test Explorer, retornando False na classe onde informamos dados inválidos(Aluno_Consistente_False), e retornando True para a classe onde passamos dados válidos(Aluno_Consistente_True).
Note que se informarmos dados inválidos no método que aguarda um boolean igual a True, o teste não passará. Veja na imagem abaixo.
Portanto, teste sempre as suas entidades sempre esperando retornos true quando as propriedades são válidas e false para propriedades inválidas.
Até aqui validamos e testamos os requisitos de CPF obrigatório e idade entre 6 e 18 anos para cadastro do aluno. Vamos agora testar o segundo requisito da entidade Aluno que exige CPF único na base.
Peraí... como vamos testar CPF único na base se ainda não temos banco de dados ?
Simples uai, basta usar um framework que permita simular uma consulta no banco. Essa é a técnica que chamamos de Mock
Passo 14 - Primeiramente, vamos criar o repositório genérico. Crie uma interface chamada "IRepository" na pasta \Domain\Interfaces\Repository
IRepository.cs
1 2 3 4 5 6 7 8 9 10 | public interface IRepository : IDisposable where TEntity : class { TEntity Adicionar(TEntity obj); TEntity ObterPorId(Guid id); IEnumerable ObterTodos(); TEntity Atualizar(TEntity obj); void Remover(Guid id); IEnumerable Buscar(Expression<Func<TEntity, bool>> predicate); int SaveChanges(); } |
Linha 1 - Estamos restringindo o parâmetro de tipo genérico a um tipo classe
Linha 8 – Busca genérica que recebe uma expressão lambda e percorre as propriedades com base nos filtros informados no parâmetro predicate.
Passo 15 - Vamos especializar o repositório genérico criando interfaces com métodos específicos para cada entidade. Veja o exemplo da interface com método específico para a entidade Aluno que herda os métodos do repositório genérico.
IAlunoRepository.cs
1 2 3 4 | public interface IAlunoRepository : IRepository { Aluno ObterPorCpf(string cpf); } |
Passo 16 - Essas interfaces já serão suficientes para validar o CPF único. Crie uma classe de especificação na pasta \Specifications\Alunos\ chamada AlunoCpfUnicoSpecification
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class AlunoCpfUnicoSpecification : ISpecification { private readonly IAlunoRepository _alunoRepository; public AlunoCpfUnicoSpecifications(IAlunoRepository alunoRepository) { _alunoRepository = alunoRepository; } public bool IsSatisfiedBy(Aluno aluno) { return _alunoRepository.ObterPorCpf(aluno.CPF) == null; } } |
Linhas 5 a 8 - Percebam que estamos passando instância dos objetos que implementam a interface IAlunoRepository por injeção de dependência.
Passo 16 - Agora vamos criar a classe de validação na pasta \Validations\Alunos\AlunoCadastroValidation.cs que herdará a classe Validator do pacote DomainValidation.
1 2 3 4 5 6 7 8 9 | public class AlunoCadastroValidation : Validator { public AlunoCadastroValidation(IAlunoRepository alunoRepository) { var cpfUnico = new AlunoCpfUnicoSpecification(alunoRepository); base.Add("cpfUnico", new Rule(cpfUnico, "CPF já cadastrado!")); } } |
Passo 17 - Estamos pronto para testar. Antes, vamos instalar o framework Rhino Mocks. Instale no projeto de testes através do comando - Install-Package RhinoMocks
Passo 18 - Vamos criar a classe que valida CPF único. No projeto de teste, crie uma pasta chamada \Validation e adicione a classe AlunoCadastroTest.cs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | public class AlunoCadastroTest { public Aluno Aluno { get; set; } [TestMethod] public void Aluno_Consistente_True() { Aluno = new Aluno() { CPF = "65560639834" }; var stubRepository = MockRepository.GenerateStub(); stubRepository.Stub(s => s.ObterPorCpf(Aluno.CPF)).Return(null); // objeto não encontrado - null var alunoValidation = new AlunoCadastroValidation(stubRepository); Assert.IsTrue(alunoValidation.Validate(Aluno).IsValid); } public void Aluno_Consistente_False() { Aluno = new Aluno() { CPF = "65560639834" }; var stubRepository = MockRepository.GenerateStub(); stubRepository.Stub(s => s.ObterPorCpf(Aluno.CPF)).Return(Aluno); // objeto encontrado var alunoValidation = new AlunoCadastroValidation(stubRepository); Assert.IsFalse(alunoValidation.Validate(Aluno).IsValid); } } |
Linhas 8 a 11 - o método cria uma instancia de Aluno atribuindo um CPF.
Na linha 12, criamos um repositório falso "stubRepository" que implementa a interface IAlunoRepository.
Na linha 13, utilizamos o método ObterPorCpf passando o cpf a ser obtido e forçando um retorno null. Podemos retornar qualquer informação aqui. Nesse caso, retornamos null pois estamos validando a especificação que retornaria do banco de dados um valor null quando o cpf não existir.
Na linha 15, a classe AlunoCadastroValidation espera receber qualquer classe que implemente IAlunoRepository e por isso passamos como parâmetro o repositório falso, stubRepository, que implementa a interface esperada pela classe.
Percebam que invertemos o resultado no método Aluno_Consistente_False retornando o próprio Aluno, simulando a existência do CPF obtido pelo método ObterPorCpf do repositório.
Até aqui, a entidade Aluno já está validando todos os requisitos - CPF válido e único na base. E lembrando que ainda não saímos da camada de domínio. Particularmente, eu considero uma boa prática implementar todas as regras de negócio no domínio e testá-las antes de seguir com o desenvolvimento das outras camadas.
No próximo post, vamos fazer a validação das entidades Matrícula e Curso utilizando classes de serviço no domínio.
Até mais!
Thanks for reading!
https://www.dnfl4949.com/sands 샌즈카지노
https://www.dnfl4949.com/theking 더킹카지노
https://www.dnfl4949.com/merit 메리트카지노
https://www.dnfl4949.com/first 퍼스트카지노
https://www.bgj4949.com/ 우리카지노사이트
https://www.bgj4949.com/gatsby 개츠비카지노
https://www.bgj4949.com/korea 코리아카지노
https://www.ekffo150.com 우리카지노사이트
Cara estou iniciando .Net e apreendendo sobre a estrutura ddd, muito bom esse tutorial, tem sido de bastante ajuda no meu aprendizado, Parabéns é pouco mew velho!!