Como testar EJBs de unidade ao usar o JPA2?

Como você faria para testar um EJB que usa JPA? Por exemplo, se eu tiver uma entidade Order e OrderEJB que deve calcular o total de um pedido (conforme definido abaixo), como eu realizaria testes unitários do EJB sem tocar no database? Além disso, como você definiria valores para suas entidades, para que possa garantir o cálculo esperado? Aqui está um exemplo de código abaixo …

@Entity public class Order { @Id private long OrderId; private LineItem[] items; } 

E um orderEJB

 @Stateless public class OrderEJB { EntityManager em; public double calculateOrderTotal(long orderId) { .. } } 

Como você faria para testar a unidade do método calculateOrderTotal se eu não conseguisse tocar no database? Eu não quero implementar um DAO porque estou tentando me afastar dessa abordagem.

Obrigado por qualquer ajuda.

Não é a teoria geral que OrderEJB e Order e LineItem são (se ignorarmos a anotação) apenas POJO e, portanto, podem ser testados em JUnit independente? Nós precisaremos simular EntityManager, e presumivelmente em

  calculateOrderTotal() 

você tem algum código que no conceito vai

  em.giveMeThisOrder(orderId) 

e você apenas zomba disso. A lógica de negócios que você está testando é direcionada pelo que o Mock retorna. A chave para isso é que você deve usar uma boa estrutura de simulação, por exemplo, JMock. Em qualquer teste você diz (obviamente não com esta syntax):

  EntitiyManager mockEm = // create the mock mockEm.check(that you are called with and order Id of 73) mockEm.please( when someone calls giveMeThisOrder return then **this** particular order) 

e assim, em cada teste, você cria exatamente a ordem que precisa para exercer algum aspecto do seu código de cálculo. Você pode muito bem ter muitos desses testes que empurram todos os casos de borda e canto do seu cálculo.

A idéia principal aqui é que o Teste de Unidade não implica dependência externa, como um Banco de Dados. O Teste de Integração pode usar um database real. Pode ser um aborrecimento para acertar as suas zombarias, criando essas instâncias de Order que podem ser bastante maçantes, mas tendem a tornar futuros testes muito mais rápidos.

Eu também sou a favor de fazer testes iniciais de integração – você encontra toda uma outra class de erros dessa maneira.

Você deu uma chance ao OpenEjb? – Se você configurar no modo incorporado, você pode executar testes de unidade do eclipse. Eu tenho zombado de injeções de gerente de entidade, etc, para teste de unidade antes, mas depois fica tedioso. Com o openejb, você pode fazer isso com menos configurações. http://openejb.apache.org/

Aqui está o que eu faço:

Primeiro você precisa configurar um database na memory para seus testes. Funciona como um database regular, mas não é armazenado em disco. Tanto o Derby quanto o HsqlDB suportam isso.

Em seu teste de unidade, crie um EntityManager manualmente e injetá-lo em sua instância EJB. Você provavelmente precisará manter uma referência ao EntityManager para poder gerenciar as transactions, da seguinte forma:

 em.getTransaction().begin(); myEjb.doSomething(x, y); em.getTransaction().commit();