blob: 67bc326ce09230dec5bcdaf47fc847cefc708f49 [file] [log] [blame]
//
// 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+].