Dúvida teste unitário service
08/02/2017 15:48
0
Na empresa onde trabalho me foi pedido para criar serviços e testes unitários para classes de serviço, só que não tenho a menor idéia de como fazer isso, até pq quase nunca criei testes antes. Não tem controller nem view, só modelo.

?
class Classificacao {
Usuario usuario
Item item
Date data = new Date()
int nota
static int obterMedia(long id){
  def item = Item.findById(id)
  def classificacoes = Classificacao.findAllByItem(item)
  int notas = 0
  int total = classificacoes.size()
  classificacoes.each{
notas+=it.nota
  }
  if(notas == 0 & total == 0)
return 0
  else
return notas/total
}
static boolean jaDeuNota(usuarioId, itemId){
  return Classificacao.findByUsuarioAndItem(Usuario.findById(usuarioId), Item.findById(itemId))
}
}


@Transactional
class ClassificacaoService {
def serviceMethod() {
}
 
@Transactional(readOnly = true)
def buscar(def classificacaoId){
  return Classificacao.findById(classificacaoId)
}
 
@Transactional
def cadastrar(Classificacao c){
  return c.save(flush:true, failOnError:true)
}
 
@Transactional(readOnly = true)
def listar(){
  Classificacao.list()
}
@Transactional
def excluir(def classificacaoId){
  buscar(classificacaoId).delete flush:true
}
}



@TestFor(ClassificacaoService)
class ClassificacaoServiceSpec extends Specification {
def setup() {
}
def cleanup() {
}
void "test something"() {
  expect:"fix me"
true == false
}
}



Como faço o teste unitário deste serviço? E meu serviço está de acordo com a versão 3.2.5?

Obs: Não sei pq fazer tanta questão de classes de serviço para métodos padrão como estes onde o grails já trata normalmente. Me parece mais coisa de programador viciado em java isso daí.
Tags: Grails, teste, unitário, serviço


1
De fato este service me parece bem inutil, só criou uma camada em cima dos métodos que o GORM já expõe nos domains.
Se realmente vc precisa testar isso, o caminho é o seguinte:
Na sua classe de teste terá um método para cada cenário que você precisa testar. Em cada método, você vai
1) Criar dados necessarios para o teste
2) Invocar o service para aquele cenário
3) Verificar o comportamento.

Exemplo:
void "O método excluir deve buscar o objeto com o id informado e excluí-lo"() {
    setup:
    def classificacao = new Classificacao()
    // define alguns dados
    classificacao.save()

    when:
    service.excluir(classificacao.id)

    then:
    Classificacao.get(classificacao.id) == null
}


0
Se isso está na pasta src/test então é um teste unitário, creio que no setup terá que chamar mockDomain(Classificacao) para habilitar o gorm para esta entidade

Pessoalmente (e isso é um gosto pessoal mesmo), eu implemento tudo como teste de integração. Neste caso você retira a anotação @TestFor, declara um atributo com o nome do service (e o service será injetado ali para você), e não precisa mais de mockDomain. E o teste passa a residir na pasta src/integration-test


0
Infelizmente não posso fazer teste de integração, precisa ser unitário mesmo.

Eu preenchi seguindo seu exemplo junto de outros que peguei na internet. Chegou nisso, mas aí esbarrei num erro que vc na segunda mensagem já trouxe a solução com o mock para habilitar o gorm.


?package br.com.conecteme.empodera.ui.servico

import grails.test.mixin.TestFor
import spock.lang.Specification
import br.com.conecteme.empodera.ui.dominio.Item
import br.com.conecteme.empodera.ui.dominio.Classificacao
import br.com.conecteme.empodera.ui.servico.ClassificacaoService

/**
 * See the API for {@link grails.test.mixin.services.ServiceUnitTestMixin} for usage instructions
 */
@TestFor(ClassificacaoService)
class ClassificacaoServiceSpec extends Specification {

    def setup() {
    }

    def cleanup() {
    }
    
    void 'excluir'() {
        setup:
            def classificacao = gerarDados()
            service.cadastrar(classificacao)
        when:
            classificacaoService.excluir(classificacao.id)
        then:
            Classificacao.get(classificacao.id) == null
    }
    
    void 'cadastrar'() {
        when:
            def classificacao = gerarDados()
            def bd = service.cadastrar(classificacao)
        then:
            assert bd.item == classificacao.item
            assert bd.data == classificacao.data
            assert bd.nota == classificacao.nota
            Classificacao.count() == 1
    }
        
//    void 'listar'() {
//        when:
//            params.sort = 'name'
//            params.max = 20
//            params.offset = 0
//            controller.list()
//        then:
//            //
//    }
    
//    void 'buscar'() {
//        when:
//        then:
//    }
    
    def gerarDados() {
        def classificacao = new Classificacao()
        classificacao.item = new Item()
        classificacao.data = new Date()
        classificacao.nota = 0
        return classificacao
    }
    
}



?java.lang.IllegalStateException: Either class [br.com.conecteme.empodera.ui.dominio.Classificacao] is not a domain class or GORM has not been initialized correctly or has already been shutdown. Ensure GORM is loaded and configured correctly before calling any methods on a GORM entity.   at org.grails.datastore.gorm.GormEnhancer.stateException(GormEnhancer.groovy:387)
at org.grails.datastore.gorm.GormEnhancer.findInstanceApi(GormEnhancer.groovy:273)
at org.grails.datastore.gorm.GormEnhancer.findInstanceApi(GormEnhancer.groovy:270)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.currentGormInstanceApi(GormEntity.groovy:1326)
at org.grails.datastore.gorm.GormEntity$Trait$Helper.save(GormEntity.groovy:151)
at br.com.conecteme.empodera.ui.servico.ClassificacaoService.$tt__cadastrar(ClassificacaoService.groovy:20)
at br.com.conecteme.empodera.ui.servico.ClassificacaoService.cadastrar_closure3(ClassificacaoService.groovy)
at groovy.lang.Closure.call(Closure.java:414)
at groovy.lang.Closure.call(Closure.java:430)
at grails.transaction.GrailsTransactionTemplate$2.doInTransaction(GrailsTransactionTemplate.groovy:96)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:133)
at grails.transaction.GrailsTransactionTemplate.execute(GrailsTransactionTemplate.groovy:93)
at br.com.conecteme.empodera.ui.servico.ClassificacaoServiceSpec.cadastrar(ClassificacaoServiceSpec.groovy:42)
09/02/2017 13:51


0
Realmente era o mock, como imaginei. Foi só acrescentar a linha abaixo que resolveu. Agora se este teste é eficienteou não, aí são outros quinhentos xD. Fora que falta eu fazer a listagem.

?@Mock([ClassificacaoService, Classificacao])
09/02/2017 14:08


0
Testes cada vez mais eficazes vem com o tempo
Uma coisa importante: Sempre que aparecer um bug na aplicação, procure criar um teste automatizado que o exponha



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto