2

次のテストケースがあります。

@ContextConfiguration("/spring/test-context.xml")
@TransactionConfiguration(transactionManager="txManager")
@Transactional()
public class MyEntityDaoTestCase extends AbstractJUnit4SpringContextTests { 

    @Autowired
    private MyEntityDao dao;

    @Test
    public void testSave_success() {
        MyEntity e = new MyEntity();
        dao.save(e);
        MyEntity result = dao.findById(e.getId());
        assertNotNull(result);      
    }
}

私のDAO定義は次のとおりです。

public abstract class MyEntityDAO {

    @PersistenceContext
    private EntityManager mEntityManager;

    public void save(MyEntity entity) {
        mEntityManager.persist(entity);
    }

    public MyEntity findById(Long id) {
        return mEntityManager.find(mEntityClass, id);
    }
}

私の春の設定は次のとおりです。

<beans xmlns="http://www.springframework.org/schema/beans" 
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans 
           http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
           http://www.springframework.org/schema/tx 
           http://www.springframework.org/schema/tx/spring-tx-3.0.xsd">

    <!-- 
        Bean post-processor for JPA annotations 
    -->
    <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor"/>

    <!--
        JPA entity manager factory 
     -->
    <bean id="jpaEntityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
      <property name="persistenceUnitName" value="unit-test-pu"/>
    </bean>

    <!--
        Transaction manager 
     -->
    <bean id="txManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="jpaEntityManagerFactory"/>
    </bean>

    <!-- 
        Enable the configuration of transactional behavior based on annotations 
    -->
    <tx:annotation-driven transaction-manager="txManager"/>

    <!--
        DAO instance beans 
     -->
    <bean id="mockEntityDao" class="mypackage.MyEntityDao"></bean>

</beans>

テストの実行中にエラーは発生しませんが、合格しません。findById() メソッドがデータベース内のエンティティを見つけられないようです。このケースを正しくテストする方法について誰かアドバイスできますか?

編集:

私の JPA プロバイダーは休止状態です。単体テストにインメモリ HSQLDB を使用しており、次の構成になっています。

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
             version="2.0">
   <persistence-unit name="unit-test-pu" transaction-type="RESOURCE_LOCAL">   
      <properties>
         <property name="javax.persistence.jdbc.driver" value="org.hsqldb.jdbcDriver"/>
         <property name="javax.persistence.jdbc.user" value="sa"/>
         <property name="javax.persistence.jdbc.password" value=""/>
         <property name="javax.persistence.jdbc.url" value="jdbc:hsqldb:."/>
         <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
         <property name="hibernate.archive.autodetection" value="class"/>
         <property name="hibernate.show_sql" value="true"/>
         <property name="hibernate.format_sql" value="true"/>
         <property name="hibernate.hbm2ddl.auto" value="create"/>
      </properties>      
   </persistence-unit>
</persistence>
4

4 に答える 4

2

@TransactionalConfiguration アノテーションと Spring JUnit ランナーを使用してみることができます。

クラスを次のように変更するようなもの:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("/spring/test-context.xml")
@TransactionConfiguration(transactionManager="txManager", defaultRollback=true)
@Transactional
public class MyEntityDaoTestCase {

これは、抽象的なケースを拡張する必要がないことも意味します (Spring ランナーを使用しているため) - そのアプローチが特に気に入らない限り。

詳細はこちら

于 2012-04-04T12:53:03.390 に答える
0

-annotationsを有効にするには、 AbstractJUnit4SpringContextTestsではなくAbstractTransactionalJUnit4SpringContextTestsを拡張する必要があると思います。@Transactional

于 2012-04-04T13:42:52.977 に答える
0

永続化レイヤーをテストしたい場合は、DBUnit の機能を調べることもできます。

Spring ベースのシナリオで永続化レイヤー (この場合は JPA) をテストすることについて、Petri Kainulainen の素晴らしい記事を見つけることができます。

http://www.petrikainulainen.net/programming/spring-framework/spring-data-jpa-tutorial-integration-testing/

これにより、DAO クラスが期待どおりに動作し、DB への書き込みと読み取りが行われるかどうかをテストします。サービス レイヤーでは、この側面のテストを回避して、ビジネス ロジックの「モック」アプローチに重点を置くことができます。

それが役に立てば幸い

フラン

于 2014-12-26T19:31:58.043 に答える
0

TDD に厳密に従う場合は、メモリ内データベースを使用するのではなく、すべてをモック化する必要があります。問題は、persist メソッドが void を返すことです。したがって、正しい応答 (データベースによって生成された ID を持つエンティティ) をテストすることはできません。

@RunWith(MockitoJUnitRunner.class)
public class CookieRepositoryTest {

@Mock
 EntityManager em;

@Mock
 TimeService timeService;

@InjectMocks
 CookieRepository underTest = new CookieRepository();

@Test
 public void testCreateEntity() throws Exception {
 Cookie newCookie = new Cookie();

when(timeService.getTime()).thenReturn(new DateTime(DateTimeZone.UTC));

doAnswer(new Answer<Brand>() {
 @Override
 public Brand answer(InvocationOnMock invocationOnMock) throws Throwable {
 Object[] args = invocationOnMock.getArguments();
 Cookie cookie = (Cookie) args[0];
 cookie.setId(1);
 return null;
 }

}).when(em).persist(any(Brand.class));

Cookie persistedCookie = underTest.createEntity(newCookie);
 assertNotNull(persistedCookie.getId());
 }

}

完全な説明は、私のブログ投稿にあります。

于 2012-07-02T16:34:57.537 に答える