Hoje vamos realizar testes em nosso CRUD para ver se tudo está certo, então mão na massa…
Vamos criar um novo projeto de testes, clique com o botão direito em cima da pasta Testes e selecione a opção Add -> New Project, e depois selecione Test -> Test Project e coloque o nome de Contatos.Business.Teste
Antes de mais nada, vamos adicionar a referência ao projeto Contatos.Business e Contatos.Factory, clique com o botão direito em cima do projeto de teste Contatos.Business.Teste e selecione a opção Add -> Reference, depois na aba Projects e selecione os projetos Contatos.Business e Contatos.Factory.
Depois de criado o projeto de teste e adicionado as referências, temos prestar atenção em alguns detalhes:
- Copiar o arquivo hibernate.cfg.xml do projeto Contatos.Factory.Teste para Contatos.Business.Teste
- Adicionar referências para as seguintes DLLs: NHibernate.dll, NHibernate.ByteCode.LinFu.dll, Npgsql.dll
Veja abaixo a estrutura do projeto:
Vamos adicionar uma nova classe de teste, clique com o botão direito em cima do projeto Contatos.Business.Teste e seleicone a opção Add -> New Test e coloque o nome de TipoTelefoneTeste.cs.
Para cada operação do CRUD vamos criar um método de teste, vamos começar com a classe mais fácil TipoTelefone, veja abaixo a implementação desses métodos.
[sourcecode language=”csharp”]
[TestMethod]
public void cadastrar()
{
TipoTelefone _tipoCelular = new TipoTelefone();
_tipoCelular.Descricao = "Tipo Celular";
TipoTelefone _tipoResidencial = new TipoTelefone();
_tipoResidencial.Descricao = "Tipo Residencial";
TipoTelefoneRepository _repository = new TipoTelefoneRepository();
_repository.Salvar(_tipoCelular);
_repository.Salvar(_tipoResidencial);
}
[TestMethod]
public void alterar()
{
TipoTelefone _obj = new TipoTelefone();
_obj.Codigo = 1;
_obj.Descricao = "Tipo do Telefone Novo";
TipoTelefoneRepository _repository = new TipoTelefoneRepository();
_repository.Alterar(_obj);
}
[TestMethod]
public void deletar()
{
TipoTelefone _obj = new TipoTelefone();
_obj.Codigo = 1;
TipoTelefoneRepository _repository = new TipoTelefoneRepository();
_repository.Excluir(_obj);
}
[TestMethod]
public void selecionarTodos()
{
TipoTelefoneRepository _repository = new TipoTelefoneRepository();
IList<TipoTelefone> fromDB = _repository.ObterTodos();
Assert.IsNotNull(fromDB);
foreach (TipoTelefone _atual in fromDB)
{
Console.WriteLine(_atual.Codigo);
Console.WriteLine(_atual.Descricao);
Console.WriteLine("——————————–");
}
}
[TestMethod]
public void selecionarCodigo()
{
TipoTelefoneRepository _repository = new TipoTelefoneRepository();
TipoTelefone fromDB = _repository.ObterPorId(4);
Assert.IsNotNull(fromDB);
Console.WriteLine(fromDB.Codigo);
Console.WriteLine(fromDB.Descricao);
}
[/sourcecode]
Resultado da execução dos testes.
Agora vamos fazer os testes com a entidade Contato, que é mais complexa que a TipoTelefone, já que a mesma possui relacionamentos com outras entidades, adicione uma nova classe de teste com o nome ContatoTeste e vamos criar os métodos de testes.
Teste Cadastrar Contato
[sourcecode language=”csharp”]
[TestMethod]
public void cadastrar()
{
// Recupera os Tipo do Telefone – vamos usar para cadastrar um Telefone
TipoTelefoneRepository tipoTelefoneRepository = new TipoTelefoneRepository();
TipoTelefone tipoCel = tipoTelefoneRepository.ObterPorId(1);
TipoTelefone tipoRes = tipoTelefoneRepository.ObterPorId(2);
// Cria um novo contato
Contato contato = new Contato();
contato.Nome = "Leandro Prado";
contato.DataNascimento = Convert.ToDateTime("30/12/1983");
contato.Sexo = ‘M’;
contato.Email = "contato@leandroprado.com.br";
contato.WebSite = "www.leandroprado.com.br";
contato.Anotacoes = "Teste com a entidade Contato";
// Lista de Grupos
GrupoRepository grupoRepository = new GrupoRepository();
IList<Grupo> lstGrupo = grupoRepository.ObterTodos();
// adiciona lista de grupos ao contato
contato.ListaGrupos = lstGrupo;
// Lista de telefones
IList<Telefone> lstTelefone = new List<Telefone>();
// Cria um tipo de telefone celular
Telefone telCelular = new Telefone();
// relaciona o telefone com o contato criado
telCelular.ContatoTelefone = contato;
telCelular.CodigoDDD = 41;
telCelular.Numero = 12345678;
telCelular.TipoTel = tipoCel;
lstTelefone.Add(telCelular);
// Cria um tipo de telefone residencial
Telefone telResidencial = new Telefone();
// relaciona o telefone com o contato criado
telResidencial.ContatoTelefone = contato;
telResidencial.CodigoDDD = 41;
telResidencial.Numero = 87654321;
telResidencial.TipoTel = tipoRes;
lstTelefone.Add(telResidencial);
// adiciona a lista de telefones ao contato
contato.ListaTelefones = lstTelefone;
// manda salvar o contato
ContatoRepository contatoRepository = new ContatoRepository();
contatoRepository.Salvar(contato);
}
[/sourcecode]
Veja abaixo o resultado da execução desse método:
Agora vamos verificar como está os resgistros no banco:
Teste Selecionar por Código do Contato
Vamos criar o método de teste para selecionar o contato cadastrado, veja abaixo o código:
[sourcecode language=”csharp”]
[TestMethod]
public void selecionarCodigo()
{
ContatoRepository contatoRepository = new ContatoRepository();
Contato fromDB = contatoRepository.ObterPorId(17);
Assert.IsNotNull(fromDB);
Console.WriteLine(fromDB.Codigo);
Console.WriteLine(fromDB.Nome);
Console.WriteLine(fromDB.Email);
Console.WriteLine(fromDB.Sexo);
Console.WriteLine(fromDB.Anotacoes);
foreach (var _tel in fromDB.ListaTelefones)
{
Console.WriteLine(_tel.CodigoDDD);
Console.WriteLine(_tel.Numero);
Console.WriteLine(_tel.TipoTel.Descricao);
Console.WriteLine("——————————–");
}
foreach (var _grp in fromDB.ListaGrupos)
{
Console.WriteLine(_grp.Nome);
Console.WriteLine(_grp.Descricao);
Console.WriteLine("——————————–");
}
contatoRepository.CloseSession();
}
[/sourcecode]
Veja o resultado da execução desse teste:
Podemos observar que o NHibernate ja recupera toda a nossa estrutura do banco, recupera o Contato -> Lista de Telefones -> Lista de Grupos.
Agora vamos criar o teste para Deletar um contato, veja abaixo:
[sourcecode language=”csharp”]
[TestMethod]
public void deletar()
{
ContatoRepository _repository = new ContatoRepository();
Contato contato = _repository.ObterPorId(17);
_repository.Excluir(contato);
}
[/sourcecode]
Podemos ver que o NHibernate ja deletou toda as tabelas filhas Telefone e ContatoGrupo, vamos verificar no banco:
Agora é só seguir o exemplos acima e criar os testes para as outras entidades, no próximo post vamos começar a criar as telas com EXT JS.
Até a próxima!
Leandro,
Na classe de Teste para inserir o contato deu uma exceção:
object references an unsaved transient instance – save the transient instance before flushing. Type: Contatos.Factory.Entity.Telefone, Entity: Contatos.Factory.Entity.Telefone
Fiz alguma coisa errada???
abs
Fernando,
Veja como esta o mapemaneto da entidade Contato… da uma conferida com a Parte 3 do tutorial
Baixe o código fonte e confere com o seu para ver se está igual…
Qualquer coisa da um grito!!
Leandro Prado
Estava diferente mesmo!!!!
vlw Leandro
Maravilha!!!
😀
Leando,
No método selecionarCodigo() meu código gerou uma exceção:
Initializing[Contatos.Factory.Entity.Contato#3]-failed to lazily initialize a collection of role: Contatos.Factory.Entity.Contato.ListaTelefones, no session or session was closed
Testei colocando lazy=”false” no Contato -> Telefones… ele retonar os valores do banco, porém ele faz a consulta SQL inteira antes de acessar as propriedades
Fernando,
Veja como está a sua classe RepositoryBase, parece alguma coisa com a conexão com a base…
Até ++
você conseguiu resolver este problema ? como ?
Estou com este mesmo problema:
No método selecionarCodigo() meu código gerou uma exceção:
Initializing[Contatos.Factory.Entity.Contato#3]-failed to lazily initialize a collection of role: Contatos.Factory.Entity.Contato.ListaTelefones, no session or session was closed
alguem conseguiu resolver ?
eu setei o Lazy para false, mas agora esta retornando o seguinte erro
Método de teste Contatos.Business.Teste.ContatoTeste.SelecionarCodigo gerou exceção:
NHibernate.LazyInitializationException: Initializing[Contatos.Factory.Entity.TipoTelefone#2]-Could not initialize proxy – no Session.
alguma ideia ?
Paulo,
esse erro acontece porque vc esta tentando recuperar um registro filho, porém a conexão já foi fechada….
De uma olhada na classe RepositoryBase compare com a sua e veja se esta igual..
att,
Leandro Prado
Só para constar, que até esta parte do tutorial não foi criado nenhum Grupo (nem teste desta entidade). Portanto a linha “IList lstGrupo = grupoRepository.ObterTodos();” tá só para bonito hehehe.
Baixei a solution da parte 5.
De onde saíram os seguintes métodos???
selecionarTelefonesContato (TelefoneRepository)
selecionarTipoTelefoneContato (TipoTelefoneRepository)
selecionarGruposContato (GrupoRepository)
Pois no tutorial eles não apareceram até agora.
Eu estou seguindo o tutorial e criando eu mesmo a minha solution (não estou baixando e rodando direto da tua. Aliás, só baixei agora porque deu erro aqui pra mim).
A solução que tá para download tem coisas a mais do que aparece no tutorial (como os métodos acima). Aí claro, como eu não tenho esses métodos ali também acabo levando o “failed to lazily initialize a collection of role: Contatos.Factory.Entity.Contato.ListaTelefones, no session or session was closed”.
Estava gostando bastante do tutorial até agora, mas esse tipo de coisa eu acho frustrante. Agora, se a idéia era só baixar os teus arquivos, bom, daí quem pede desculpas sou eu que entendi mal o propósito desse tutorial.
Cleiton
Realmente esses métodos não estão no tutorial, apenas estou demostrando o CRUD, por esse motivo que está disponivel o download do projeto compilando
Esse erro do Lazy acontece porque a conexão com o NHibernate esta fechada, por isso que tive que criar aqueles novos métodos para preencher as listas
Para resolver esse problema e fazer o lazy automaticamente temos que mudar o modo de conexão do NHinernate para HttpModule, Usando NHibernate com ASP NET MVC
att,
Leandro Prado
Opa Leandro
Valeu cara, vou dar uma olhada ali neste link depois.
Desculpe pelo meu “tom” no comentário anterior, lendo agora percebo que fui meio estúpido.
Mas estou começando agora com ORM, e uma informação omitida como essa acaba causando bastante confusão. Então fica só minha “crítica” nesse sentido, de que se o tutorial “não bate” com o arquivo de download seria bom avisar, enfim, acho que me fiz entender.
Fora isso, parabéns pela iniciativa. Apesar deste pequeno inconveniente, foi um ótimo tutorial.
Bom dia Leandro,
To tentando rodar o teste no NUnit devido aos problemas de rodar no teste do VS e ao rodar dá o seguinte erro:
“Contatos.Business.Teste.TipoTelefoneTeste.cadastrar:
System.Exception : Could not find a getter for property ‘WebSite’ in class ‘Contatos.Factory.Entity.Contato'”
O que devo proceder?
Abraços.
Rodrigo,
Veja na sua classe Contato está faltando uma propriedade com o nome WebSite
Não esqueça que as propriedades tem que ser ‘virtual’
att,
Leandro Prado
Leandro,
Não to conseguindo fazer a parte de persistência, já fiz uma classe httpModule e tals, mas ele não roda nem o teste e quando eu debugo na parte de obter todos, tendo eu 2 registros no banco, a lista vem zerada!
Posso te mandar o projeto por e-mail?
Pode me passar o seu e-mail?
Fico no aguardo
Rodrigo,
Está gerando algum erro?
Baixe o projeto e tente comparar com o seu, para ver se acha o que está errado..
att,
Leandro Prado
Boa tarde Leandro,
Realmente eu “marquei toca”, na minha classe de Contato o WebSite estava “Website”, por isso do problema na hora de rodar o teste.
Agora rodou tudo certinho, muito bom, verifiquei alguns métodos que você colocou nas interfaces também e agora deu tudo certinho.
Obrigado pela atenção e por sua iniciativa.
maravilha Rodrigo!!! sempre erramos eu pequenas coisas.. hehehe!!
até ++
att,
Leandro Prado
Leandro, muito grato pelo tutorial, ajudou muito. Acredito que o pessoal como eu está esquecendo de colocar a opção “Copy always” no hibernate.cfg.xml do projeto teste Contatos.Business.Teste. Desde faço um apelo que faça o mesmo projeto com a nova versão do nhibernate sem a utilização dos arquivos hbm.xml, por favor continue com os tutos.
Boa tarde Leandro,
Para utilizar outro banco de dados é necessario alterar apenas o arquivo hibernate.cfg.xml, ou tem mais alguma alteração?
Quero utilizar o SQL Server 2008
Alessandra
Você deverá alterar a conexão no arquivo hibernate.cfg.xml e também alterar o item nos arquivos de mapeamentos das classes, porque o ID no Postgress é gerado através de uma sequence, e no SQL Server é gerado automaticamente
Então ficaria mais ou menos assim
generator class=”guid”
Veja que o generator mudou!
Espero que tenha ajudado
att,
Leandro Prado