2016-01-28 462 views
1

我想爲我的無狀態ejb + jpa演示代碼編寫一個junit測試。我認爲這實際上不是一個junit測試,而是一個集成測試。無狀態ejb + jpa的junit測試

我有一個無狀態的ejb,使用注入的EntityManager和PostgreSQL數據庫服務器。我使用CDI(Spring並未在我的項目中使用)和EclipseLink與persistent.xml文件。我的應用程序將在GlassFish服務器上執行。

我想寫一個檢查完整邏輯的測試:在我的示例無狀態ejb上調用一個方法,並將數據保存到內存數據庫中。我想用我的測試啓動內存數據庫,並在執行測試類時停止它。

EJB類:

@Stateless 
public class PropertyServiceImpl implements PropertyService { 

    @PersistenceContext(name = "anything-jndi-em") 
    private EntityManager em; 

    public String getStringValue(final String key) { 
     Property property = em.createNamedQuery("Property.findByKey", Property.class) 
       .setParameter("key", key) 
       .getSingleResult(); 

     return property.getValue(); 
    } 
} 

enitity類:

@Entity 
@Table(name = "APPLICATION_SETTING") 
@NamedQueries({ 
     @NamedQuery(name = "Property.findByKey", query = "select a from Property a where a.key = :key and a.status = 1") 
}) 
public class Property 
{ 
    @Id 
    @SequenceGenerator(name = "APPLICATION_SETTING_SEQ", sequenceName = "APPLICATION_SETTING_SEQ", allocationSize = 1) 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "APPLICATION_SETTING_SEQ") 
    @Column(name = "ID", unique = true, nullable = false) 
    private Long id; 

    @Column(name = "KEY", length = 200, nullable = false) 
    private String key; 
    ... 
} 

如果我是正確的,我需要按照下面的步驟:

  1. 創建一個新的文件persistent.xml將連接到內存中的dadabase並將其放在/ test/Resources/META-INF文件夾下的正確的jdbc連接參數
  2. 添加一些POM依賴關係的內存數據庫(例如:HSQLDB)和嵌入式EJB容器
  3. 創建一個簡單的PropertyServiceImplTest.java類
  4. 配置莫名其妙的/測試/資源/ META-INF /持續性。 xml文件將用戶通過我的測試類
  5. 初始化嵌入式EJB容器並啓動內存數據庫
  6. 執行我的六月測試方法:

@Test public void testGetStringValue() { PropertyService service = new PropertyServiceImpl(); assertNotNull(service.getStringValue("abc")); }

你能幫我寫一個適合這個場景的正確的測試java類嗎?

+0

你嘗試了嗎? –

回答

0

在您的實際測試用例中啓動了javax.ejb.embeddable.EJBContainer。之後,使用javax.naming.Context來查找你的無狀態bean。你可以像你習慣的那樣使用你的bean並聲明它的行爲。請記住,與完整吹出的ejb容器相比,可嵌入容器impl只需支持一個子集(ejb lite)。 Here你找到一個非常整潔的例子。

代碼片段:

JBContainer ejbContainer = EJBContainer.createEJBContainer(); 
Context ctx = ejbContainer.getContext(); 
PropertyService service = (PropertyService) ctx.lookup("java:global/classes/PropertyServiceImpl"); 
assertNotNull(service.getStringValue("abc")); 
0

我強烈建議Arquillian。我在Wildfly 8,9和10上使用它。一旦安裝正確,這可能有點艱鉅,它會產生奇蹟。

你只需要批註JUnit測試,如下所示:

@RunWith(Arquillian.class) 
public class MRSInjectionServiceTests extends ... 

,然後提供一個部署檔案我通過JBoss的拆封做:

@Deployment 
public static WebArchive createDeployment() { 
    return ShrinkWrap.create(ZipImporter.class, "MRSInjectionServiceTests.war").importFrom(new File(ROOT_WAR_DEPLOYMENT_LOCATION)).as(WebArchive.class); 
} 

然後你可以運行從行家這些集成測試或gradle。Arquillian將根據您的配置運行您的應用服務器容器(Wildfly,GLassfish等),並將運行JUnit測試作爲整個系統運行的系統測試。

這是非常好的。非常值得努力。

+0

我檢查的Arquillian,它看起來很有趣。THX! – zappee

0

我想與您分享我的解決方案。根據你的幫助,我看了一下Arquillian的文檔,最後我能夠創建一個適當的集成測試。 我的測試使用帶有HSQL內存數據庫的GlassFish嵌入式EE容器。

測試java類:

@RunWith(Arquillian.class) 
public class PropertyServiceImplTest { 

    @EJB 
    private PropertyService propertyService; 

    @Deployment 
    public static JavaArchive createTestArchive() { 
     return ShrinkWrap.create(JavaArchive.class, "test.jar"). 
       .addPackage(Property.class.getPackage()) 
       .addPackage(PropertyService.class.getPackage()) 
       //.addPackage(PropertyServiceImpl.class.getPackage()) 
       addAsResource("META-INF/persistence.xml"); 
    } 

    @Test 
    public void testGetStringValue() { 
     assertNotNull(propertyService); 

     Property property = new Property(); 
     property.setKey("aaa"); 
     property.setValue("5"); 
     propertyService.setStringValue(property); 

     assertEquals(propertyService.getStringValue("aaa"), "5"); 
    } 
} 

的persistence.xml爲目標的數據庫

  • 有效值:eclipselink doc

    <persistence-unit name="example" transaction-type="JTA"> 
        <jta-data-source>jdbc/my-ds</jta-data-source> 
        <class>a.b.domain.Property</class> 
        <properties> 
         <property name="eclipselink.target-database" value="HSQL"/> 
         <property name="eclipselink.ddl-generation" value="drop-and-create-tables"/> 
         <property name="eclipselink.logging.level" value="ALL"/> 
        </properties> 
    </persistence-unit> 
    

arquillian.xml

如何消除瘋狂 「發現潛在的問題」 的警告信息? DatatypeFactory屬性必須設置。

WARNING: Potential problem found: The configured data type factory 
     'class org.dbunit.dataset.datatype.DefaultDataTypeFactory' might cause problems with the current database 
      'HSQL Database Engine' (e.g. some datatypes may not be supported properly). In rare cases you might see this 
      message because the list of supported database products is incomplete (list=[derby]). If so please request a 
      java-class update via the forums.If you are using your own IDataTypeFactory extending DefaultDataTypeFactory, 
      ensure that you override getValidDbProducts() to specify the supported database products. 
  • DBUnit的具體設置:jboss documentation
  • 數據類型的工廠:dbunit documentation

    <engine> 
        <property name="deploymentExportPath">target/arquillian</property> 
    </engine> 
    
    <container default="true" qualifier="glassfish"> 
        <configuration> 
         <property name="resourcesXml">myproject/src/test/resources/glassfish-resources.xml</property> 
        </configuration> 
    </container> 
    
    <extension qualifier="persistence"> 
        <property name="defaultDataSource">jdbc/my-ds</property> 
    </extension> 
    
    <extension qualifier="persistence-dbunit"> 
        <property name="datatypeFactory">org.dbunit.ext.hsqldb.HsqldbDataTypeFactory</property> 
    </extension> 
    

與GlassFish resources.xml中

<resources> 
    <jdbc-connection-pool name="jdbc/my-pool" 
          res-type="javax.sql.DataSource" 
          datasource-classname="org.hsqldb.jdbc.JDBCDataSource"> 
     <property name="PortNumber" value="9001" /> 
     <property name="serverName" value="localhost" /> 
     <property name="URL" value="jdbc:hsqldb:mem:arquillian" /> 
     <property name="user" value="sa" /> 
     <property name="password" value="" /> 
    </jdbc-connection-pool> 

    <jdbc-resource jndi-name="jdbc/my-ds" pool-name="jdbc/my-pool" /> 
</resources> 

項目結構:

  • 的src /測試/ JAVA/abPropertyServiceImplTest.java
  • 的src /測試/資源/ META-INF/persistence.xml中
  • 的src /測試/資源/的Arquillian。 XML
  • 的src /測試/資源/ GlassFish的-resources.xml中
0

我很失望後,我花了3-4天的Arquillian。

我閱讀了關於這個測試框架的文檔,我用它創建了一個很好的環境。有創建美麗的xml文件與prod和測試環境的佔位符和pom文件完成。一切工作正常,我簡單的ejb和實體Java類。

今天我已經開始研究我真正的java 8應用程序。過了一段時間發生了一些事情,因爲我的測試失敗了。當我從代碼中移除lambda表達式時,我的測試再次正常工作。

所以當我使用lambda表達式時,注入的ejb總是空的: @EJB private ConfigurationService configurationService;

GlassFish Managed 3.1 Container的最新版本是1.0.0.CR4,發佈日期:2013-04-29。這是很老:(

的Arquillian GlassFish的模塊是完全無用的:(