Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Тестирование EJB бинов / 9 сообщений из 9, страница 1 из 1
09.12.2015, 13:51
    #39124100
denis111111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
Добрий день

Стоит задача протестировить EJB бины
Готового решения от Oracle не нашел
Поиск по гугл не дал нормального результата
Пробывал создавать динимачески свой контейнер в тестах - долго, иногда глючит
Пробывал как говорили копировать домен Глассфыша в папку проэкта, тоже не работает

Единственное что роботает это сделать бины @Remote и вызывать из через @EJB клиет, но тогда нужно все время деплоить их на сервер

Как вы тестируете @EJB?
...
Рейтинг: 0 / 0
09.12.2015, 14:08
    #39124121
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
denis111111,

Не очень понятно что именно тестировать собрались. Если обычные юнит-тесты, то EJB 3 это же теперь POJO с аннотациями. Инъектишь зависимости и проверяешь методы. Или есть задача полный цикл протестировать?
...
Рейтинг: 0 / 0
09.12.2015, 14:08
    #39124123
WGA
WGA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
denis111111Как вы тестируете @EJB? http://arquillian.org/
...
Рейтинг: 0 / 0
09.12.2015, 14:28
    #39124150
denis111111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
Blazkowiczdenis111111,

Не очень понятно что именно тестировать собрались. Если обычные юнит-тесты, то EJB 3 это же теперь POJO с аннотациями. Инъектишь зависимости и проверяешь методы. Или есть задача полный цикл протестировать?

Я бы так и тестировал, но много методов пишет данные в БД, значит нужны транзакции, а у меня транзакции неявно делает EJB контейнер
Также в меня много EJB инъекций бинов
например
@EJB
private SomeService someService;

Если тестировать как POJO я банально не смогу вставить someService, так как нет метода setSomeService(SomeService someService)

WGA http://arquillian.org/

Надо посмотреть...
...
Рейтинг: 0 / 0
09.12.2015, 14:32
    #39124155
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
denis111111@EJB
private
SomeService someService;

Если тестировать как POJO я банально не смогу вставить someService, так как нет метода setSomeService(SomeService someService)

Только неделю назад об этом писал: Every time you inject to a field, a unit test dies.
Юнит тесты строго диктуют правила написания кода. Нельзя просто так наговнокодить и потом писать для этого тесты.
И ещё, как я уже писал в предыдущей теме, package private модификатор рулит.
...
Рейтинг: 0 / 0
09.12.2015, 14:35
    #39124160
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
denis111111Я бы так и тестировал, но много методов пишет данные в БД, значит нужны транзакции, а у меня транзакции неявно делает EJB контейнер
Это уже не unit test будет, ну никак. А для интеграционных тестов, я тоже не вижу никакой сложности. Инжектим какой-то EM для тестов. Уверен готовый решений для этого полно. А транзакцию вручную стартуем перед дестом сценария.
...
Рейтинг: 0 / 0
09.12.2015, 14:59
    #39124193
denis111111
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
Blazkowicz,

Согласен
Буду смотреть в сторону интеграционных тестов
у меня нельзя открыть транзакцию, выполнить метод, закрить, так как для внутренней логики нужно делать несколько комитов во время выполнения метода.

Вам приходилось тестировать EJB через интеграционные тесты, если да, то как?
...
Рейтинг: 0 / 0
10.12.2015, 22:39
    #39125397
WGA
WGA
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
Blazkowiczdenis111111Я бы так и тестировал, но много методов пишет данные в БД, значит нужны транзакции, а у меня транзакции неявно делает EJB контейнер
Это уже не unit test будет, ну никак. А для интеграционных тестов, я тоже не вижу никакой сложности. Инжектим какой-то EM для тестов. Уверен готовый решений для этого полно. А транзакцию вручную стартуем перед дестом сценария.При наличии CMT будет затруднительно все это проделать. Стандарту JEE лучше всего соответствует сервер приложений )
Хочешь достоверных тестов для сценариев с транзакциями - поднимай интеграционные тесты с реальным контейнером. ИМХО.

У нас сформировался следующий типовой подход к тестированию. В основном системы это REST- и SOAP-сервисы. Так что и тестируем непосредственно внешнее API. Пишем абстрактный класс, например, BaseTest. В нем содержатся все тесты. От него наследуются два потомка: AppIT и AppFT. Первый - тесты в контейнере (Glassfish Embedded или Wildfly Embedded с недавних пор). Второе основное различие - при IT некоторые системы могут быть подменены моками с использованием механизама @Alternative из CDI, в FT же все честно, вызываем реальные методы. Соответственно некоторые тесты в FT отключаем перекрывая родительский метод.

В AppIT поднимается контейнер с использованием Arquillian. Обращение к ресурсам на localhost и каком-нибудь случайном порту, чтобы тесты не конфликтовали. В BaseTest адрес не определен, получаем от потомка. AppFT принимает адрес из системных свойств, можно "натравить" тесты на любой тестовый сервер. Можно использовать и для мониторинга текущего состояния, а не только при сборке. Учитывая, что все задачи - интеграционные очень помогает выяснить что и когда отвалилось из внешних систем.

Ну и, наконец, встраиваем все это в Maven сборку. Настраиваем maven-surefire-plugin игнорить тесты с **/*IT.java и **/*FT.java, а maven-failsafe-plugin учим выполнять только **/*IT.java и **/*FT.java в зависимости от профиля. Так можно собрать тесты как с интеграционными тестами, так и без них. Учитывая, что выполняются они долго это полезно. Кстати, чтобы сэкономить на поднятии контейнера классов тестов делаем немного и они иногда получаются очень большими. Есть такой недостаток.

Все описанное можно применить и для тестирования отдельных EJB. Все еще проще - делаем @Inject EJB-бина, вызываем его методы. Я в качестве эксперимента делал такие тесты. Даже научил откатывать транзакцию после исполнения каждого теста. Все как в spring-testing ))

Реальный пример.
Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
public abstract class BaseTest {
    private static final Logger LOG = LoggerFactory.getLogger(BaseTest.class);

    private static WebTarget target;

    protected static void init(String baseUrl) {
        if (target == null) {
            target = RestHelper.configureTarget(baseUrl, LOG);

            String login = "test_user1";
            String password = "qwerty";
            Response response = target.
                    path("/users/login")
                    .request()
                    .buildPost(Entity.entity(new LoginRequest(login, password), MediaType.APPLICATION_JSON_TYPE))
                    .invoke();

            AuthResponse authResponse = response.readEntity(AuthResponse.class);
            assertEquals(200, response.getStatus());
            OtpChallenge otpChallenge = authResponse.getOtpChallenge();
            assertNotNull(otpChallenge);
            assertNotNull(otpChallenge.getOperationId());
            assertNotNull(otpChallenge.getMaskedPhone());
            assertEquals(Integer.valueOf(60), otpChallenge.getTimeout());


            Response newOtpResponse = target.path("/operation/new-otp")
                    .request()
                    .buildPost(Entity.entity(new OtpReply(otpChallenge.getOperationId(), null), MediaType.APPLICATION_JSON_TYPE))
                    .invoke();
            newOtpResponse.readEntity(OtpChallenge.class);

            Response response1 = target.path("/operation/confirm")
                    .request()
                    .buildPost(Entity.entity(new OtpReply(otpChallenge.getOperationId(), "112233"), MediaType.APPLICATION_JSON_TYPE))
                    .invoke();

            AuthResponse authResponse1 = response1.readEntity(AuthResponse.class);
            assertNull(authResponse1.getOtpChallenge());
            assertTrue(authResponse1.getError().isEmpty());

            NewCookie sessionCookie = response.getCookies().get("JSESSIONID");

            target.register(new CookieSessionFilter(sessionCookie));
        }
    }

    @Test
    public void testAuthWithWrongPassword() throws Exception {
        Response response = target.
                path("/users/login")
                .request()
                .buildPost(Entity.entity(new LoginRequest("test_user1", "qwerty_"), MediaType.APPLICATION_JSON))
                .invoke();
        assertEquals(429, response.getStatus());
        AuthResponse authResponse = response.readEntity(AuthResponse.class);
        assertNull(authResponse.getOtpChallenge());
        assertEquals(1, authResponse.getError().size());
        ErrorResponse errorResponse = authResponse.getError().get(0);
        assertEquals("401", errorResponse.getCode());
        assertEquals("Подвердите, что Вы не робот", errorResponse.getErrorMessage());
    }

    @Test
    public void testGetProducts() throws Exception {
        Response response = target.path("/products")
                .request()
                .get(Response.class);
        assertEquals(200, response.getStatus());
        ProductListResponse products = response.readEntity(ProductListResponse.class);
        assertFalse(products.getProducts().isEmpty());
    }

}

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
@RunWith(Arquillian.class)
public class AppIT extends BaseTest {

    @Deployment
    public static Archive<?> deploy() {
        return TestHelper.createDeployableArchive();
    }

    @Before
    public void setupSuite() {
        init("http://localhost:8080/apppath/rs");
    }
}

Код: java
1.
2.
3.
4.
5.
6.
public class AppFT extends BaseTest {
    @BeforeClass
    public static void initSuite() {
        init("https://api.server.com/rs");
    }
}

...
Рейтинг: 0 / 0
11.12.2015, 08:04
    #39125486
Alexey Tomin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Тестирование EJB бинов
denis111111Я бы так и тестировал, но много методов пишет данные в БД, значит нужны транзакции, а у меня транзакции неявно делает EJB контейнер
Также в меня много EJB инъекций бинов
например
@EJB
private SomeService someService;

Если тестировать как POJO я банально не смогу вставить someService, так как нет метода setSomeService(SomeService someService)

WGA http://arquillian.org/

Надо посмотреть...

TestNG поддерживает @inject от guice. Поэтому у меня проблем нет :D
А вот для EJB'шных...
Наверное лучше всего будет сделать переменные package-visible и вставлять моки в @Before.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Тестирование EJB бинов / 9 сообщений из 9, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]