// 
//     Licensed to the Apache Software Foundation (ASF) under one
//     or more contributor license agreements.  See the NOTICE file
//     distributed with this work for additional information
//     regarding copyright ownership.  The ASF licenses this file
//     to you under the Apache License, Version 2.0 (the
//     "License"); you may not use this file except in compliance
//     with the License.  You may obtain a copy of the License at
// 
//       http://www.apache.org/licenses/LICENSE-2.0
// 
//     Unless required by applicable law or agreed to in writing,
//     software distributed under the License is distributed on an
//     "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
//     KIND, either express or implied.  See the License for the
//     specific language governing permissions and limitations
//     under the License.
//

= Using the Embedded EJB Container to Test Enterprise Applications
:jbake-type: tutorial
:jbake-tags: tutorials 
:jbake-status: published
:icons: font
:syntax: true
:source-highlighter: pygments
:toc: left
:toc-title:
:description: Using the Embedded EJB Container to Test Enterprise Applications - Apache NetBeans
:keywords: Apache NetBeans, Tutorials, Using the Embedded EJB Container to Test Enterprise Applications

This tutorial demonstrates how to create and run JUnit tests for a Java EE enterprise application. In this tutorial you will create a web application with an entity class and a session bean. You will first create a JUnit test class for the session bean and run the test in the embedded EJB container. You will then add an entity class to the project and modify the test class to add a test method for the entity class.

*Tutorial Exercises*

* <<Exercise_1,Testing a Session Bean>>
* <<Exercise_1a,Creating the Project>>
* <<Exercise_1b,Creating the Session Bean>>
* <<Exercise_1c,Testing the Session Bean>>
* <<Exercise_1d,Modifying the Test to Specify Container Properties>>
* <<Exercise_1e,Using @BeforeClass and @AfterClass Annotations>>
* <<Exercise_2,Testing an Entity Class>>
* <<Exercise_2a,Creating the Entity Class>>
* <<Exercise_2b,Modifying the Session Bean>>
* <<Exercise_2c,Testing the Entity Class>>
* <<Exercise_3,Downloading the Solution Project>>

*To follow this tutorial, you need the following software and resources.*

|===
|Software or Resource |Version Required 

|link:/downloads/[+NetBeans IDE+] |7.2, 7.3, 7.4, 8.0, Java EE bundle 

|link:http://www.oracle.com/technetwork/java/javase/downloads/index.html[+Java Development Kit (JDK)+] |version 7 or 8 

|GlassFish Server Open Source Edition |3.1.x or 4.x 
|===

NOTE: This tutorial requires the JUnit plugin. If you did not install the JUnit plugin when you installed the IDE, open the Plugins manager, select the Available plugins tab and install the JUnit plugin.

*Prerequisites*

This document assumes you have some basic knowledge of, or programming experience with, the following technologies:

* Java Programming
* NetBeans IDE

Before starting this tutorial you may want to familiarize yourself with the following documents.

* link:javaee-gettingstarted.html[+Getting Started with Java EE Applications+]
* link:../java/junit-intro.html[+Writing JUnit Tests in NetBeans IDE+]
* link:http://download.oracle.com/docs/cd/E19798-01/821-1754/gjlde/index.html[+Using the EJB 3.1 Embeddable API with Embedded GlassFish Server+]

You can download link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FWebAppJUnit.zip[+a zip archive of the finished project+].


== Testing a Session Bean

In this section you will create a simple Java EE web application that will contain a session bean and an entity class.


=== Creating the Project

1. Choose File > New Project (Ctrl-Shift-N; ⌘-Shift-N on Mac) from the main menu.
2. Select Web Application from the Java Web category. Click Next.
3. Name the project *WebAppJUnit* and set the project location.
4. Deselect the Use Dedicated Folder option, if selected.
Click Next.

[start=5]
. Set the server to *GlassFish Server* and set the Java EE Version to *Java EE 6 Web* or *Java EE 7 Web*. 
Click Finish.


=== Creating the Session Bean

In this exercise you will create a very simple session bean that contains one method that adds two numbers.

1. Right-click the WebAppJUnit project in the Projects window and choose New > Other.
2. Select Session Bean in the Enterprise JavaBeans category. Click Next.
3. Type *MyBean* as the EJB Name.
4. Type *bean* for the Package name.
5. Select Stateless as the Session Type. Click Finish.

When you click Finish, the new class opens in the editor.


[start=6]
. In the editor, add the following method  ``addNumbers``  to the class.

[source,java]
----

@Stateless
public class MyBean {
    *public int addNumbers(int numberA, int numberB) {
        return numberA + numberB;
    }*
}
----

NOTE: It is not necessary to add an  ``@LocalBean``  annotation or implement an interface in this tutorial. By default the bean exposes a no-interface view when no view is explicitly specified.


[start=7]
. Save your changes.


=== Testing the Session Bean

In this exercise you will create a test class for the session bean that will test the  ``addNumbers``  method. The IDE can generate the new test class and skeleton test methods based on the methods in the target class.

1. Right-click the  ``MyBean``  class in the Projects window and choose Tools > Create Tests.
2. Select JUnit in the Frameworks dropdown list.
3. Use the default values in the Create Tests dialog box. Click OK.

image::images/create-tests-dialog.png[title="Create Tests dialog"]

NOTE:  The first time that you create a JUnit unit test you need to specify the JUnit version. Select JUnit 4.x in the Select JUnit Version dialog box and click Select.

When you click OK, the IDE generates the  ``MyBeanTest.java``  file and opens the class in the editor.

In the Projects window you can see that the IDE generated the test class under the Test Packages node. By default, the IDE generates a skeleton test method in the test class that calls  ``javax.ejb.embeddable.EJBContainer.createEJBContainer()``  to create an EJB container instance. The  ``createEJBContainer()``  method is one of the methods in the link:http://download.oracle.com/javaee/6/api/javax/ejb/embeddable/EJBContainer.html[+  ``EJBContainer`` +] class that is part of the EJB 3.1 Embeddable API.

If you expand the Test Libraries node in the Projects window, you can see that the IDE automatically added GlassFish Server (embeddable container) and JUnit 4.x as test libraries. If you expand the GlassFish Server library, you can see that the library contains the  ``glassfish-embedded-static-shell.jar`` .

image::images/embedded-static-shell-jar.png[title="Structure of project in the Projects window"]

NOTE:  The  ``glassfish-embedded-static-shell.jar``  JAR does not contain the sources for the embedded EJB container. The  ``glassfish-embedded-static-shell.jar``  JAR requires a local installation of GlassFish. The classpath for the local GlassFish installation is determined by the target server for the project. You can change the target server in the project's Properties dialog box.


[start=4]
. Modify the generated skeleton test method to specify values for  ``numberA`` ,  ``numberB``  and  ``expResult``  and remove the default call to fail.

[source,java]
----

@Test
public void testAddNumbers() throws Exception {
    System.out.println("addNumbers");
    *int numberA = 1;
    int numberB = 2;*
    EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer();
    MyBean instance = (MyBean)container.getContext().lookup("java:global/classes/MyBean");
    *int expResult = 3;*
    int result = instance.addNumbers(numberA, numberB);
    assertEquals(expResult, result);
    container.close();
}
----

[start=5]
. Right-click the project in the Projects window and choose Test.

When you run the test, the Test Results window opens in the IDE and displays the progress and results of the test.

image::images/test-results1.png[title="Test Results window"]

You will see output similar to the following in the Output window.


[source,java]
----

Testsuite: bean.MyBeanTest
addNumbers
...
Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 31.272 sec

------------- Standard Output ---------------
addNumbers
...
------------- ---------------- ---------------
test-report:
test:
BUILD SUCCESSFUL (total time: 35 seconds)
----


=== Modifying the Test to Specify Container Properties

When you used the Create Tests wizard, the IDE generated a default skeleton test class that contained code for starting the EJB container. In this exercise you will modify the generated code that starts the container to enable you to specify additional properties for the embedded container instance.

1. Add the following code (in bold) to the test class.

[source,java]
----

@Test
public void testAddNumbers() throws Exception {
    System.out.println("addNumbers");
    int numberA = 1;
    int numberB = 2;

    // Create a properties map to pass to the embeddable container:
    *Map<String, Object> properties = new HashMap<String, Object>();*
    // Use the MODULES property to specify the set of modules to be initialized,
    // in this case a java.io.File 
    *properties.put(EJBContainer.MODULES, new File("build/jar"));*

    // Create the container instance, passing it the properties map:
    EJBContainer container = javax.ejb.embeddable.EJBContainer.createEJBContainer(*properties*);

    // Create the instance using the container context to look up the bean 
    // in the directory that contains the built classes
    MyBean instance = (MyBean) container.getContext().lookup("java:global/classes/MyBean");

    int expResult = 3;

    // Invoke the addNumbers method on the bean instance:
    int result = instance.addNumbers(numberA, numberB);

    assertEquals(expResult, result);

    // Close the embeddable container:
    container.close();
}
----

[start=2]
. Right-click in the editor and choose Fix Imports (Alt-Shift-I; ⌘-Shift-I on Mac) to add import statements for  ``java.util.HashMap``  and  ``java.util.Map`` .

[start=3]
. Run the test again to confirm that the modified test works and that the container is created correctly.

You can click the Rerun button in the Test Results window.

 


=== Using  ``@BeforeClass``  and  ``@AfterClass``  Annotations

In this exercise you will modify the test class to create individual methods for creating and shutting down the container instance. This can be useful when you want to run several tests that can use the same container instance. In this way you do not need to open and close a container instance for each test, and instead create one instance that is created before the tests are run and is then closed after all the tests are completed.

In this exercise you will move the code that creates the EJB container to the  ``setUpClass``  method. The  ``setUpClass``  method is annotated with  ``@BeforeClass``  that is used to indicate a method that will be run first, before the other methods in the test class. In this example, the container instance will be created before the  ``testAddNumbers``  test method and the container will exist until it is shut down.

Similarly, you will move the code that shuts down the container to the  ``tearDownClass``  method that is annotated with  ``@AfterClass`` .

1. Add the following field to the test class.

[source,java]
----

private static EJBContainer container;
----

[start=2]
. Copy the code that creates the container from the  ``testAddNumbers``  test method to the  ``setUpClass``  method and

[source,java]
----

@BeforeClass
public static void setUpClass() *throws Exception* {
    *Map<String, Object> properties = new HashMap<String, Object>();
    properties.put(EJBContainer.MODULES, new File("build/jar"));
    container = EJBContainer.createEJBContainer(properties);
    System.out.println("Opening the container");*
}
----

[start=3]
. Copy the code that closes the container from the  ``testAddNumbers``  test method to the  ``tearDownClass``  method.

[source,java]
----

@AfterClass
public static void tearDownClass() *throws Exception* {
    *container.close();
    System.out.println("Closing the container");*
}
----

[start=4]
. Remove the redundant code from the  ``testAddNumbers``  method. Save your changes.

The test class should now look like the following.


[source,java]
----

public class MyBeanTest {
    private static EJBContainer container;

    public MyBeanTest() {
    }

    @BeforeClass
    public static void setUpClass() throws Exception {
        Map<String, Object> properties = new HashMap<String, Object>();
        properties.put(EJBContainer.MODULES, new File("build/jar"));
        container = EJBContainer.createEJBContainer(properties);
        System.out.println("Opening the container");
    }

    @AfterClass
    public static void tearDownClass() throws Exception {
        container.close();
        System.out.println("Closing the container");
    }

    @Before
    public void setUp() {
    }

    @After
    public void tearDown() {
    }

    /**
     * Test of addNumbers method, of class MyBean.
     */ 
    @Test
    public void testAddNumbers() throws Exception {
        System.out.println("addNumbers");
        int numberA = 1;
        int numberB = 2;

        // Create the instance using the container context to look up the bean 
        // in the directory that contains the built classes
        MyBean instance = (MyBean) container.getContext().lookup("java:global/classes/MyBean");

        int expResult = 3;

        // Invoke the addNumbers method on the bean instance:
        int result = instance.addNumbers(numberA, numberB);

        assertEquals(expResult, result);
    }
}
----

If you run the test again to confirm that the container is created and shut down correctly, you will see output similar to the following in the Test Results window.

image::images/test-results2a.png[title="Test Results window"]

You can see that the  ``setUpClass``  method ran before the  ``addNumbers``  test and printed "Opening the container".


== Testing an Entity Class

In this section you will create an entity class and persistence unit and modify the session bean to inject the entity manager and access the entities. You will add a simple method to the new entity class that prints the id number of the entry to the output. You will then add some simple methods to the session bean to create and verify entries in the database.


=== Creating the Entity Class

In this section you will use the New Entity Class wizard to create an entity class and persistence unit with the database connection details.

1. Right-click the WebAppJUnit project in the Projects window and choose New > Other.
2. Select Entity Class in the Persistence category. Click Next.
3. Type *SimpleEntity* as the Class Name.
4. Select bean from the Package dropdown list.
5. Type *int* as the Primary Key Type. Click Next.
6. Use the default Persistence Unit Name and Persistence Provider.
7. Select  ``jdbc/sample``  as the data source and Drop and Create as the strategy. Click Finish.

image::images/create-entity-wizard.png[title="Create Entity Class dialog"]

When you click Finish, the new entity class opens in the editor. If you expand the Configuration Files node in the Projects window, you can see that the IDE automatically generated the  ``persistence.xml``  file that defines the properties of the persistence unit  ``WebAppJUnitPU`` .


[start=8]
. In the editor, add the following private field to the entity class.

[source,java]
----

private String name;
----

[start=9]
. Right-click in the Source Editor and choose Insert Code (Alt-Insert; Ctrl-I on Mac) and select Getter and Setter to open the Generate Getters and Setters dialog box.

[start=10]
. Select the  ``name``  field in the dialog box. Click Generate.

[start=11]
. Add the following method to the class.

[source,java]
----

public SimpleEntity(int id) {
    this.id = id;
    name = "Entity number " + id + " created at " + new Date();
}
----

[start=12]
. Use the  ``@NamedQueries``  and  ``@NamedQuery``  annotations to create a named SQL query.

[source,java]
----

@Entity
*@NamedQueries({@NamedQuery(name = "SimpleEntity.findAll", query = "select e from SimpleEntity e")})*
public class SimpleEntity implements Serializable {
----

[start=13]
. Create a default constructor.

You can click the suggestion icon that is displayed in the gutter next to the class declaration if you want the IDE to generate the constructor for you.


[start=14]
. Fix your imports to add import statements for  ``javax.persistence.NamedQueries`` ,  ``javax.persistence.NamedQuery``  and  ``java.util.Date`` . Save your changes.

In addition to the default generated code, the entity class should now look similar to the following:


[source,java]
----

package bean;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;


@Entity
@NamedQueries({@NamedQuery(name = "SimpleEntity.findAll", query = "select e from SimpleEntity e")})
public class SimpleEntity implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private int id;

    private String name;

    public SimpleEntity() {
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public SimpleEntity(int id) {
        this.id = id;
        name = "Entity number " + id + " created at " + new Date();
    }

    

    ...

}
----


=== Modifying the Session Bean

In this exercise you will edit the  ``MyBean``  session bean to add methods for inserting and retrieving data to the database table.

1. Open  ``MyBean.java``  in the editor.
2. Right-click in the editor and choose Insert Code (Alt-Insert; Ctrl-I on Mac) and choose Use Entity Manager from the popup menu.

When you chose Use Entity Manager, the IDE added the following code to the class to inject the entity manager. You can see that the name of the persistence unit is generated automatically.


[source,java]
----

@PersistenceContext(unitName="WebAppJUnitPU")
private EntityManager em;
----

[start=3]
. Add the following  ``verify``  and  ``insert``  methods.

[source,java]
----

@PermitAll
public int verify() {
    String result = null;
    Query q = em.createNamedQuery("SimpleEntity.findAll");
    Collection entities = q.getResultList();
    int s = entities.size();
    for (Object o : entities) {
        SimpleEntity se = (SimpleEntity)o;
        System.out.println("Found: " + se.getName());
    }

    return s;
}

@PermitAll
public void insert(int num) {
    for (int i = 1; i <= num; i++) {
        System.out.println("Inserting # " + i);
        SimpleEntity e = new SimpleEntity(i);
        em.persist(e);
    }
}
----

[start=4]
. Fix your imports to import  ``javax.persistence.Query``  and save your changes.


=== Testing the Entity Class

In this exercise you will edit the test class to add a method to test that the application is able to look up the EJB and that the  ``insert``  and  ``verify``  methods are behaving correctly.

1. Start the JavaDB database.
2. Open the  ``MyBeanTest.java``  test class in the editor.
3. Edit the test class to add the following  ``testInsert``  test method.

[source,java]
----

@Test
public void testInsert() throws Exception {

    // Lookup the EJB
    System.out.println("Looking up EJB...");
    MyBean instance = (MyBean) container.getContext().lookup("java:global/classes/MyBean");

    System.out.println("Inserting entities...");
    instance.insert(5);
    int res = instance.verify();
    System.out.println("JPA call returned: " + res);
    System.out.println("Done calling EJB");

    Assert.assertTrue("Unexpected number of entities", (res == 5));
    System.out.println("..........SUCCESSFULLY finished embedded test");
}
----

[start=4]
. Right-click the project node in the Projects window and choose Test from the popup menu.

The Test Results window will open and display output that is similar to the following.

image::images/test-results2b.png[title="Test Results window after adding testInsert test"]

You can see the progress of the tests and the order in which the tests were run from the print messages that were added to the test class.

Now that you have a test for your session bean and know that your entity class connection works, you can start coding a web interface for the application. 


== Downloading the Solution Project

You can download the solution to this tutorial as a project in the following ways.

* Download link:https://netbeans.org/projects/samples/downloads/download/Samples%252FJavaEE%252FWebAppJUnit.zip[+a zip archive of the finished project+].
* Checkout the project sources from the NetBeans Samples by performing the following steps:
1. Choose Team > Subversion > Checkout from the main menu.
2. In the Checkout dialog box, enter the following Repository URL:
 ``https://svn.netbeans.org/svn/samples~samples-source-code`` 
Click Next.

[start=3]
. Click Browse to open the Browse Repository Folders dialog box.

[start=4]
. Expand the root node and select *samples/javaee/WebAppJUnit*. Click OK.

[start=5]
. Specify the Local Folder for the sources (the local folder must be empty).

[start=6]
. Click Finish.

When you click Finish, the IDE initializes the local folder as a Subversion repository and checks out the project sources.


[start=7]
. Click Open Project in the dialog that appears when checkout is complete.

NOTE: You need a Subversion client to checkout the sources. For more about installing Subversion, see the section on link:../ide/subversion.html#settingUp[+Setting up Subversion+] in the link:../ide/subversion.html[+Guide to Subversion in NetBeans IDE+].


link:/about/contact_form.html?to=3&subject=Feedback:%20Using%20the%20Embedded%20EJB%20Container[+Send Feedback on This Tutorial+]



== See Also

For more information about using NetBeans IDE to develop Java EE applications, see the following resources:

* link:javaee-intro.html[+Introduction to Java EE Technology+]
* link:javaee-gettingstarted.html[+Getting Started with Java EE Applications+]
* link:../web/quickstart-webapps.html[+Introduction to Developing Web Applications+]
* link:../../trails/java-ee.html[+Java EE &amp; Java Web Learning Trail+]

You can find more information about using EJB 3.1 Enterprise Beans in the link:http://download.oracle.com/javaee/6/tutorial/doc/[+Java EE 6 Tutorial+].

To send comments and suggestions, get support, and keep informed on the latest developments on the NetBeans IDE Java EE development features, link:../../../community/lists/top.html[+join the nbj2ee mailing list+].

