#unit-testing #ejb-3.0 #mockito #ejb-3.1 #openejb
#модульное тестирование #ejb-3.0 #mockito #ejb-3.1 #openejb
Вопрос:
Я провожу небольшое исследование по модульному тестированию EJB 3.1. В конце моя цель — создать простое в использовании решение для модульного тестирования EJB 3.1.
- У меня не так много знаний о больших реализациях EJB, и поэтому я хотел бы сначала получить несколько опытных рук (вас), чтобы просто поделиться своими идеями о том, что сложно в модульном тестировании EJB.
- Благодаря первоначальному исследованию, которое я уже провел, я могу понять преимущества использования макетных фреймворков для модульного тестирования вместо использования встроенных контейнеров. Хотя оба хороши, макетные фреймворки стоят немного выше, когда дело доходит до модульного тестирования. Встроенные контейнеры, конечно, очень хороши и имеют свои преимущества, но могут быть другой фазой модульного тестирования. Я все еще считаю, что по крайней мере в некоторых сценариях использования таких фреймворков должны быть некоторые недостатки, которые можно улучшить.
Я надеюсь, что смогу создать полное решение для модульного тестирования EJB, которым я смогу поделиться на этом форуме после завершения.
Спасибо за вашу поддержку.
Ответ №1:
Моим советом вам было бы не попадать в общую ловушку, которую я вижу, а именно думать, что вам нужно выбирать между издевательством и использованием встроенного контейнера EJB.
Вы можете использовать оба, вы должны использовать оба, и там, где вам сложно использовать оба, вы должны требовать лучшей поддержки и большего количества функций от вашего контейнера EJB.
Конечно, вы найдете людей в OpenEJB, которые действительно поддерживают и более чем рады добавить функции, чтобы помочь получить лучшее из обоих миров. Почти все действительно хорошие функции были созданы по запросам пользователей, пытающихся делать очень специфические вещи и обнаруживающих, что это сложно.
Стандартный API EJBContainer
package org.superbiz.stateless.basic;
import junit.framework.TestCase;
import javax.ejb.embeddable.EJBContainer;
public class CalculatorTest extends TestCase {
private CalculatorBean calculator;
/**
* Bootstrap the Embedded EJB Container
*
* @throws Exception
*/
protected void setUp() throws Exception {
EJBContainer ejbContainer = EJBContainer.createEJBContainer();
Object object = ejbContainer.getContext().lookup("java:global/simple-stateless/CalculatorBean");
assertTrue(object instanceof CalculatorBean);
calculator = (CalculatorBean) object;
}
Полный исходный код здесь
Это сканирует путь к классу и загружает все компоненты.
Нет сканирования, более простой подход к издевательству
Немного другой подход, когда вы определяете все в коде. Очевидно, что издеваться проще, поскольку вы можете по желанию предоставлять макетные реализации компонентов, где это необходимо.
@RunWith(ApplicationComposer.class)
public class MoviesTest extends TestCase {
@EJB
private Movies movies;
@Resource
private UserTransaction userTransaction;
@PersistenceContext
private EntityManager entityManager;
@Module
public PersistenceUnit persistence() {
PersistenceUnit unit = new PersistenceUnit("movie-unit");
unit.setJtaDataSource("movieDatabase");
unit.setNonJtaDataSource("movieDatabaseUnmanaged");
unit.getClazz().add(Movie.class.getName());
unit.setProperty("openjpa.jdbc.SynchronizeMappings", "buildSchema(ForeignKeys=true)");
return unit;
}
@Module
public EjbJar beans() {
EjbJar ejbJar = new EjbJar("movie-beans");
ejbJar.addEnterpriseBean(new StatefulBean(MoviesImpl.class));
return ejbJar;
}
@Configuration
public Properties config() throws Exception {
Properties p = new Properties();
p.put("movieDatabase", "new://Resource?type=DataSource");
p.put("movieDatabase.JdbcDriver", "org.hsqldb.jdbcDriver");
p.put("movieDatabase.JdbcUrl", "jdbc:hsqldb:mem:moviedb");
return p;
}
@Test
public void test() throws Exception {
userTransaction.begin();
try {
entityManager.persist(new Movie("Quentin Tarantino", "Reservoir Dogs", 1992));
entityManager.persist(new Movie("Joel Coen", "Fargo", 1996));
entityManager.persist(new Movie("Joel Coen", "The Big Lebowski", 1998));
List<Movie> list = movies.getMovies();
assertEquals("List.size()", 3, list.size());
for (Movie movie : list) {
movies.deleteMovie(movie);
}
assertEquals("Movies.getMovies()", 0, movies.getMovies().size());
} finally {
userTransaction.commit();
}
}
}
Конечный результат
Заманчиво сосредоточиться на различиях между различными типами тестирования и т. Д., Но, Безусловно, есть что сказать в пользу прагматичной середины. Лично я не вижу ничего плохого в возможности максимально плавно смешивать стили «unit» и «integration».
Конечно, это замечательная цель. Идеи и пожелания, которые помогут нам приблизиться, очень приветствуются.
Комментарии:
1. Привет, Дэвид, большое спасибо за ваш ответ. Я также думал о смешивании обоих подходов, что помогло бы извлечь выгоду из обоих подходов.
Ответ №2:
На самом деле существует два разных типа тестирования, которые вы, возможно, захотите рассмотреть (не исключительные):
- Модульное тестирование: в конце концов, ваши EJB — это POJO, и поэтому вы можете использовать предпочитаемую среду модульного тестирования (например, JUnit), а также mocking framework, такую как Mockito или EasyMock.
- Интеграционное тестирование: здесь вы хотите протестировать EJB, как если бы они были в контейнере (не изолированно), и поэтому вам нужно как-то эмулировать этот контейнер. Вы все еще можете использовать свою платформу модульного тестирования для кодирования своих тестов (например, JUnit), но теперь вы тестируете, как эти EJB ведут себя в контейнере и взаимодействуют с другими соавторами (например, другими EJB), которые у них могут быть. Для этого я бы рекомендовал Arquillian
Комментарии:
1. Спасибо за ваш вклад. Я в основном сосредоточен на упрощении модульного тестирования с помощью функций, чтобы сделать его максимально элегантным и простым для разработчика. Но, как вы также упоминали, лучшим подходом было бы сочетание как UT, так и интеграционного тестирования с использованием встроенных контейнеров, поскольку 2 фазы UT кажутся хорошим подходом.
Ответ №3:
Вы можете использовать Needle для модульных тестов компонентов Java EE.
Needle — это облегченный фреймворк для изолированного тестирования компонентов Java EE вне контейнера. Это сокращает код настройки тестирования за счет анализа зависимостей и автоматического внедрения макетных объектов.