Портативное решение Java EE 7 для интеграции и модульного тестирования

Я пытаюсь найти портативное решение для тестирования моего приложения Java EE 7. Это особенно сложно при тестировании EJB и их внедрений. Например:

@org.junit.Test
    public void testIsValidCredentials() throws Exception {
        System.out.println("isValidCredentials");
        String username = "";
        String password = "";

        Map properties = new HashMap();
        properties.put(EJBContainer.MODULES, new File[] {new File("target/classes")});

        EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer();
        AuthenticatorLocal instance = (AuthenticatorLocal) container.getContext().lookup("java:global/classes/Authenticator");
        boolean expResult = false;
        boolean result = instance.isValidCredentials(username, password);
        assertEquals(expResult, result);
        container.close();
    }

Когда я запускаю тест, я получаю:

Нет доступного провайдера EJBContainer

Я также пытался использовать вариант properties.put(EJBContainer.PROVIDER, ""), но безуспешно. Для Glassfish есть некоторая документация, но для Wildfly она очень плохая.

Также я слышал об arquillian, но я вижу только пакеты Alpha, что не кажется безопасным для производства. Кто-нибудь знает портативное решение для (интеграционного) тестирования?


person Albert Bos    schedule 30.12.2015    source источник
comment
Рассматривали ли вы Arquillian?   -  person John Ament    schedule 01.01.2016


Ответы (1)


Вот довольно стандартный подход, который я использую для выполнения тестов JUnit в среде Java EE.

Основная идея такова:

  1. Напишите простое тестовое приложение с тестовым сервлетом и любым компонентом EJB, который вы хотите протестировать.
  2. Используйте набор тестов JavaSE JUnit, чтобы запустить сервер приложений и направить запросы GET на тестовый сервлет.
  3. Поместите свою фактическую тестовую логику в тестовый сервлет, таким образом, ваша тестовая логика будет выполняться в среде Java EE.

Вот иллюстрация того, как это может выглядеть:

Используйте пакет JUnit SE с базовыми тестовыми заглушками для передачи запросов GET в ваше приложение:

@BeforeClass
public static void oneTimeSetUp() {
    // start my app server and make sure apps are installed
}

@AfterClass
public static void oneTimeTearDown() {
    // shut down app server
}

@Test
public void testApplicationAvailable() {
    runTestInServlet("testApplicationAvailable");
}

@Test
public void testThatFails() {
    runTestInServlet("testThatFails");
}

private void runTestInServlet(String testName) {
    // Construct the URL, note that the name of the test is passed in
    // as the value of the "test" parameter.  This will get read from
    // the servlet's doGet method
    URL url = new URL("http://localhost:9080/myAppName/testServletName?test=" + test);
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    try{
        con.setRequestMethod("GET");
        InputStream is = con.getInputStream();
        InputStreamReader isr = new InputStreamReader(is);
        BufferedReader br = new BufferedReader(isr);

        // use the BufferedReader to validate response from test servlet
        // i.e. search for some "successful test" token
    } finally {
        con.disconnect();
    }
}

Используйте соответствующие методы в тестовом сервлете для выполнения настоящего теста в среде Java EE:

@WebServlet(name = "TestServlet", urlPatterns = { "/testServletName" })
public class TestServlet extends HttpServlet {

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) 
      throws ServletException, IOException {
        String test = request.getParameter("test");
        PrintWriter out = response.getWriter();

        try {
            System.out.println("-----> " + test + " starting");
            // Use reflection to branch out and invoke the method found in the GET method's "test" parameter
            getClass().getMethod(test, PrintWriter.class).invoke(this, response.getWriter());
            System.out.println("<----- " + test + " successful");
        } catch (Throwable x) {
            System.out.println("<----- " + test + " failed:");
        } finally {
            out.flush();
            out.close();
        }
    }

    public void testApplicationAvailable(PrintWriter pw) throws Exception {
        System.out.prinln("Application and test servlet available");
    }

    public void testThatFails(PrintWriter pw) throws Exception {
        throw new Exception("This test will fail");
    }
}

Есть сторонние библиотеки, которые вы можете использовать, чтобы сделать это немного проще, но это основная идея. Показанные здесь примеры можно реализовать со стандартными библиотеками Java (и, конечно же, со средой Java EE). Единственное, что здесь относится к тому, на каком сервере приложений вы работаете, — это логика запуска и остановки сервера.

Кроме того, я слышал хорошие отзывы об Arquillian, но в последний раз я слышал, что он поддерживается только для нескольких избранных серверов приложений Java EE, что нарушает ваши требования к переносимости.

person Andy Guibert    schedule 30.12.2015