Как выполнить модульное тестирование EJB при использовании JPA2? - PullRequest
3 голосов
/ 30 сентября 2010

Как бы вы пошли о модульном тестировании EJB, который использует JPA?Например, если у меня есть сущность Order и и OrderEJB, который должен рассчитать сумму заказа (как определено ниже), как бы я провел модульное тестирование EJB, не касаясь базы данных?Кроме того, как бы вы определили значения для ваших сущностей, чтобы вы могли утверждать ожидаемый расчет?Ниже приведен пример кода ...

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

И порядок EJB

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

Как бы вы пошли о модульном тестировании метода convertOrderTotal, если я не могу коснуться базы данных?Я не хочу внедрять DAO, потому что пытаюсь отойти от этого подхода.

Спасибо за любую помощь.

Ответы [ 3 ]

4 голосов
/ 01 октября 2010

Вы пробовали OpenEjb?- Если вы устанавливаете во встроенном режиме, вы можете в значительной степени запустить модульные тесты из Eclipse.Я уже смоделировал инъекции менеджера сущностей и т. Д. Для модульного тестирования, но потом это становится утомительным.С openejb вы можете сделать это с меньшими настройками.http://openejb.apache.org/

4 голосов
/ 01 октября 2010

Разве общая теория о том, что OrderEJB и Order and LineItem являются (если мы игнорируем аннотацию) только POJO и, следовательно, может быть протестирована в автономном JUnit? Нам нужно будет смоделировать EntityManager, и предположительно в

 calculateOrderTotal()

у вас есть код, который по идее идет

 em.giveMeThisOrder(orderId)

и вы просто издеваетесь над этим. Затем проверяемая логика бизнеса зависит от того, что возвращает Mock. Ключом к этому является то, что вы должны использовать хороший фреймворк, например JMock. В любом заданном тесте вы говорите (явно не с этим синтаксисом):

 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)

и поэтому в каждом тесте вы создаете именно тот порядок, который вам необходим для выполнения некоторого аспекта кода калькуляции. У вас может быть много таких тестов, которые выдвигают все крайние и угловые случаи вашего вычисления.

Ключевая идея здесь заключается в том, что модульный тест не предполагает никаких внешних зависимостей, таких как база данных. Интеграционное тестирование может использовать реальную базу данных. Это может быть хлопотно, чтобы правильно настроить свои макеты, создание этих экземпляров Order может быть довольно скучным, но это, как правило, значительно ускоряет будущее тестирование.

Я также предпочитаю проводить раннее интеграционное тестирование - таким образом вы обнаружите целый другой класс ошибок.

0 голосов
/ 01 октября 2010

Вот что я делаю:

Сначала вам нужно настроить базу данных в памяти для ваших тестов.Он работает так же, как обычная база данных, но не хранится на диске.И Derby, и HsqlDB поддерживают это.

В своем модульном тесте создайте EntityManager вручную и вставьте его в свой экземпляр EJB.Возможно, вам потребуется сохранить ссылку на EntityManager, чтобы вы могли управлять транзакциями, например:

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