title: How can I bind a DataSource to an InitialContext for JUnit testing?
body: <p>I'm trying to run JUnit tests on database "worker" classes that do a jndi lookup on an <code>InitialContext</code> to get a <code>DataSource</code>. The worker classes are usually running on a Glassfish v3 App Server which has the appropriate jdbc resources defined.</p>
  
  <p>The code runs just fine when deployed on the App Server but doesn't run from the JUnit testing environment, because obviously it can't find the jndi resources.  So I tried to setup an InitialContext in the test class that binds a datasource to the appropriate context, but it doesn't work.</p>
  
  <p>Here is the code I have in the test</p>
  
  <pre><code>@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);
      }
  }
  </code></pre>
  
  <p>Then the <code>DataWorker</code> class has a method with the following code, more or less  </p>
  
  <pre><code>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
  }
  </code></pre>
  
  <p>If I change the<br>
  <code>ic.createSubContext("java:/comp/env/jdbc");</code><br>
  <code>ic.bind("java:/comp/env/jdbc/TestDS",testDS)</code>;<br>
  lines to<br>
  <code>ic.createSubContext("jdbc");</code><br>
  <code>ic.bind("jdbc/TestDS",testDS);</code><br>
  The worker class is able to find the DataSource, but fails giving an error saying that "username failed to login to the server".</p>
  
  <p>If I pass the DataSource that I create in the JUnit method directly into the worker, it can connect and run queries.  </p>
  
  <p><strong>So, I would like to know how to bind a DataSource that can be looked up by the worker class without being in the Web Container.</strong></p>