1

我正在尝试寻找一种可移植的解决方案来测试我的 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 提供程序

我也尝试使用 option properties.put(EJBContainer.PROVIDER, ""),但没有成功。Glassfish 有一些可用的文档,但对于 Wildfly,它真的很差。

我也听说过 arquillian,但我只看到 Alpha 包,这似乎不安全。有谁知道用于(集成)测试的便携式解决方案?

4

1 回答 1

0

这是我用来在 Java EE 环境中执行 JUnit 测试的相当标准的方法。

基本思想是:

  1. 使用测试 Servlet 和您想要测试的任何 EJB 编写一个简单的测试应用程序
  2. 使用 JavaSE JUnit 测试套件启动您的应用服务器,并将 GET 请求发送到测试 servlet
  3. 将您的实际测试逻辑放在测试 servlet 中,这样您的测试逻辑将在 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();
    }
}

在测试 servlet 中使用相应的方法在 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 应用程序服务器,这会破坏您的可移植性要求。

于 2015-12-30T14:59:46.093 回答