-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
PR para viabilizar uso de frameworks de Mock #1
base: master
Are you sure you want to change the base?
Conversation
Correção de NullPointerException no método shutdown. Este método é executado automaticamente pelo Weld ao encerrar o teste JUnit e consequentemente, a classe SeBootstrap do package demoiselle.internal captura o evento e ele tenta pegar uma instância null de requestContext.
AfterStartupProccess do startup. Ao inicializar o BlockJUnit4ClassRunner com a referência do container Weld recém inicializado já é suficiente para as injeções funcionarem. Além disso, o lançamento dos eventos AfterStartupProccess e AfterShutdownProcess são desnecessários para o contexto do JUnit (eles, inclusive, podem lançar NullPointerException em alguns casos).
Remover a inicialização dos escopos impede o uso de qualquer injeção cuja entidade pertença a esse escopo. Por exemplo, tente criar um teste que injeta algum filho de JPACrud ou EntityManager e verá que você vai receber um erro de escopo não ativo. Pode ser uma boa ideia tornar o levantamento desses escopos opcional, mas remove-los inviabiliza certos testes que não usam mocks. @zyc, o que acha? |
Oi, @Dancovich e @zyc . Efetuei um teste de execução utilizando o projeto de teste do Bookmark e executei o BookmarkBCTest que o próprio arquétipo cria e os testes passaram com sucesso com a atualização proposta no DemoiselleRunner, já que estes contextos são específicos do CDI e não tem conexão direta com JPACrud e/ou EntityManager. O Demoiselle e o CDI conseguem injetar o EntityManager normalmente sem a necessidade desses contextos. Concordo que a verificação de null dos escopos poderia ser efetuada no próprio SeBootstrap. Acredito que essa correção também pode ser feita lá. Mas também acho que a tentativa de levantar os contextos RequestContext, SessionContext, ViewContext e ConversationContext para um teste JUnit não me parecem fazer muito sentido, pois fico com a impressão de que estes contextos fazem mais sentido no contexto web. Classes que se utilizam de atributos injetados com esse contexto poderiam ser testados unitariamente utilizando mocks ou ser testados de forma integrada utilizando o Arquillian. |
O motivo pelo qual seu teste funcionou é porque existe um Bootstrap no Demoiselle Core que também levanta escopos. Faça o teste, implemente a seguinte chamada dentro de qualquer método de BookmarkBCTest:
Se realmente nenhum escopo foi levantado esse método deve lançar uma exceção. Aqui ele retornou uma instância de Agora sobre o conceito de uso de escopos durante testes é necessário estabelecermos o contexto de uso do DemoiselleRunner. Em testes unitários "puros" concordo que levantar contextos não fazem sentido, mas a verdade é que também não faz sentido o uso de CDI ou qualquer dos outros subsistemas fornecidos por um servidor de aplicação. Em tal teste qualquer utilitário externo à unidade sendo testada deve ser "mockada". Devido a isso em tal situação o recomendado é simplesmente não usar o DemoiselleRunner. Se a injeção de dependência é essencial para seu teste então provavelmente não se trata de um teste unitário, mas de integração. Um exemplo típico é testar se o sistema de paginação usando a classe Pagination funciona, o teste pode consistir em injetar seu ManagedBean que define a página atual desejada e injetar seu DAO e verificar se o Pagination manteve as configurações ao ser injetado no DAO. O sistema de paginação no Demoiselle é RequestScoped então é necessário levantar esse escopo para testar corretamente esse sistema. O Arquillian pode ser usado nesses casos como você disse. Na verdade o Demoiselle JUnit surgiu quando o Arquillian ainda não era maduro o suficiente para ser usado em projetos em produção e era necessário um sistema que levantasse um contexto CDI "light" para executar tais testes de integração. Seu valor ainda existe para pequenos testes de integração onde a configuração do Arquillian seriam muito custosa e onde tudo que precisamos é do sistema de injeção funcionando. Em todo caso é interessante explorar a possibilidade de tornar o levantamento de escopos opcional. Em certos testes precisamos do sistema de injeção mas não de escopos ou até mesmo podemos desejar testar se certos sistemas podem ser usados sem um escopo ativo, por exemplo quando desejamos testar se um método pode ser chamado durante o evento Poderiamos discutir uma arquitetura para tal, talvez uma anotação opcional no teste? O que acham @zyc @emersonsdo @ednaraoliveira @lusabo ? |
Sugestão de modificação no DemoiselleRunner para viabilizar o uso de framework de mocks, como por exemplo, o Mockito.
Desvincula o DemoiselleRunner dos eventos lançados pelo CDI para o Demoiselle inicializar RequestContext, SessionContext, ViewContext e ConversationContext na classe SeBootstrap. Acredito que estes escopos nem devem fazer parte de um teste JUnit e a tentativa da criação dos mesmos estavam inviabilizando o uso do DemoiselleRunner em testes de unidade com mocks.
Favor avaliar esta correção para próxima versão, @emersonsdo , @zyc , @Dancovich , @ednaraoliveira