example drivermanager data create java jdbc junit glassfish datasource

drivermanager - pool connection java jdbc example



¿Cómo puedo enlazar un DataSource a un InitialContext para la prueba de JUnit? (2)

La última vez que intenté algo como esto hace unos años, finalmente me di por vencido y lo reformulé: en ese momento, NO podías crear un DataSource fuera de un contenedor. Tal vez puedas, ahora, tal vez alguien se burla de algo.

Aún así, eso huele ... No debería tener NINGÚN código de "lógica de negocios" que dependa directamente de las fuentes de datos o las búsquedas de JNDI o similares. Eso es toda la plomería para ser conectados juntos fuera de su código.

¿Qué tan flexible es su diseño? Si su código bajo prueba depende directamente de un DataSource (o incluso obtiene su propia conexión), refactorícelo. Inyectar una conexión le permitirá probar todo lo que quiera con JDBC, incluso utilizando una implementación en memoria, y evitarle tener que apuntalar una gran cantidad de infraestructura innecesaria (para la prueba, de todos modos) para hacerlo.

Esta pregunta ya tiene una respuesta aquí:

Estoy intentando ejecutar pruebas JUnit en clases de "trabajo" de base de datos que hacen una búsqueda jndi en un InitialContext para obtener un DataSource . Las clases de trabajo generalmente se ejecutan en un servidor de aplicaciones Glassfish v3 que tiene definidos los recursos jdbc apropiados.

El código se ejecuta correctamente cuando se implementa en el servidor de aplicaciones, pero no se ejecuta desde el entorno de prueba de JUnit, porque obviamente no puede encontrar los recursos jndi. Así que intenté configurar un InitialContext en la clase de prueba que vincula una fuente de datos al contexto apropiado, pero no funciona.

Aquí está el código que tengo en la prueba.

@BeforeClass public static void setUpClass() throws Exception { try { // Create initial context System.setProperty(Context.INITIAL_CONTEXT_FACTORY, "org.apache.naming.java.javaURLContextFactory"); System.setProperty(Context.URL_PKG_PREFIXES, "org.apache.naming"); InitialContext ic = new InitialContext(); ic.createSubcontext("java:"); ic.createSubcontext("java:/comp"); ic.createSubcontext("java:/comp/env"); ic.createSubcontext("java:/comp/env/jdbc"); // Construct DataSource SQLServerConnectionPoolDataSource testDS = new SQLServerConnectionPoolDataSource(); testDS.setServerName("sqlserveraddress"); testDS.setPortNumber(1433); testDS.setDatabaseName("dbname"); testDS.setUser("username"); testDS.setPassword("password"); ic.bind("java:/comp/env/jdbc/TestDS", testDS); DataWorker dw = DataWorker.getInstance(); } catch (NamingException ex) { Logger.getLogger(TitleTest.class.getName()).log(Level.SEVERE, null, ex); } }

Entonces la clase DataWorker tiene un método con el siguiente código, más o menos

InitialContext ic = null; DataSource ds = null; Connection c = null; PreparedStatement ps = null; ResultSet rs = null; String sql = "SELECT column FROM table"; try{ ic = new InitialContext(); ds = (DataSource) ic.lookup("jdbc/TestDS"); c = ds.getConnection(); ps = c.prepareStatement(sql); // Setup the Prepared Statement rs = ps.executeQuery(); if(rs.next){ //Process Results } }catch(NamingException e){ throw new RuntimeException(e); }finally{ //Close the ResultSet, PreparedStatement, Connection, InitialContext }

Si cambio el
ic.createSubContext("java:/comp/env/jdbc");
ic.bind("java:/comp/env/jdbc/TestDS",testDS) ;
líneas a
ic.createSubContext("jdbc");
ic.bind("jdbc/TestDS",testDS);
La clase de trabajo puede encontrar el DataSource, pero falla al dar un error que dice que "el nombre de usuario no pudo iniciar sesión en el servidor".

Si paso el DataSource que creo en el método JUnit directamente al trabajador, se puede conectar y ejecutar consultas.

Por lo tanto, me gustaría saber cómo enlazar un DataSource que la clase trabajadora puede buscar sin estar en el contenedor web.


También encontré ese ejemplo como incorrecto. Esto funcionó para mí.

ic.createSubcontext("java:comp"); ic.createSubcontext("java:comp/env"); ic.createSubcontext("java:comp/env/jdbc"); final PGSimpleDataSource ds = new PGSimpleDataSource(); ds.setUrl("jdbc:postgresql://localhost:5432/mydb"); ds.setUser("postgres"); ds.setPassword("pg"); ic.bind("java:comp/env/jdbc/mydb", ds);

La diferencia que notará es que el ''/'' después de ''java:'' en cada uno de los contextos es incorrecto y no debería estar allí.