【问题标题】:Spring Hibernate Repository Testing with jUnit使用 jUnit 进行 Spring Hibernate 存储库测试
【发布时间】:2015-06-23 08:19:10
【问题描述】:

首先我是Spring + Hibernate开发的新手。学习了大量的教程书籍,我创建了一个示例应用程序,主要基于 Spring、Hibernate 基于标准,我已经开始为存储库 (DAO) 方法编写一些测试用例,即 find、findAll、save、delete。

当我执行测试类时,并不是所有的测试用例都能正确执行,这真的很疯狂。特别是 find & findAll 方法。但是当单独运行它们时,它们完美地通过了。

实体

@Entity
@Table(name = "client_master")
public class ClientMaster {

private Long id;
private Long version;
private Date dateCreated;
private Date lastUpdated;
private String clientName;

private List<ProjectMaster> projectMaster;

@Id
@GeneratedValue
public Long getId() {
    return id;
}

public void setId(Long id) {
    this.id = id;
}

@Version
@Column(name = "version")
public Long getVersion() {
    return version;
}

public void setVersion(Long version) {
    this.version = version;
}

@Column(name = "client_name", nullable= false,unique= true)
public String getClientName() {
    return clientName;
}

public void setClientName(String clientName) {
    this.clientName = clientName;
}

@OneToMany(targetEntity = ProjectMaster.class, mappedBy = "lientMaster", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
public List<ProjectMaster> getProjectMaster() {
    return projectMaster;
}

public void setProjectMaster(List<ProjectMaster> ProjectMaster) {
    this.projectMaster = projectMaster;
}

@Column(name = "date_created" , nullable= false)
@Temporal(TemporalType.TIMESTAMP)
public Date getDateCreated() {
    return dateCreated;
}

public void setDateCreated(Date dateCreated) {
    this.dateCreated = dateCreated;
}

@Column(name = "last_updated")
@Temporal(TemporalType.TIMESTAMP)
public Date getLastUpdated() {
    return lastUpdated;
}

public void setLastUpdated(Date lastUpdated) {
    this.lastUpdated = lastUpdated;
}

}  

存储库

import java.util.List;
import javax.persistence.EntityNotFoundException;
import org.hibernate.Query;

@Repository("clientMasterRepo")
@Transactional
public class ClientMasterRepoHibernate implements ClientMasterRepository {

@Autowired
private SessionFactory sessionFactory;

@Override
public ClientMaster find(Long id) {     
    // Based on the Hibernate currentsession get the ClientMaster Object based on Id        
    ClientMaster clientMaster = (ClientMaster) sessionFactory.getCurrentSession().get(ClientMaster.class, id);              
    return clientMaster;
}

@Override
public List<ClientMaster> findAll() {
    // Get all the ClientMaster records.
    Query query = sessionFactory.getCurrentSession().createQuery("FROM ClientMaster");
    List<ClientMaster> clientMasterList = query.list();
    return clientMasterList;

}

@Override
public ClientMaster save(ClientMaster clientMaster) {
    // Insert or Update the ClientMaster object
    sessionFactory.getCurrentSession().saveOrUpdate(clientMaster);
    return CclientMaster;       
}

@Override
public void delete(ClientMaster clientMaster) {
    // Delete the ClientMaster object
    sessionFactory.getCurrentSession().delete(clientMaster);
}

}

JUnit 测试

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"file:src/main/resources/META-INF/spring/spring-master.xml"})  
public class ClientMasterRepositoryTests {

@Autowired
private ClientMasterRepository clientMasterRepository;

private List<ClientMaster> ClientMasterList;

@Before
public void setup(){
    // Initialize ClientMaster mock objects for testing     
    ClientMasterList = new ArrayList<ClientMaster>();

    ClientMaster client1 = new ClientMaster();
    client1.setClientName("Client1");
    client1.setDateCreated(new Date());
    client1.setLastUpdated(new Date());

    ClientMaster client2 = new ClientMaster();
    client2.setClientName("Client2");
    client2.setDateCreated(new Date());
    client2.setLastUpdated(new Date());

    ClientMaster client3 = new ClientMaster();
    client3.setClientName("Client3");
    client3.setDateCreated(new Date());
    client3.setLastUpdated(new Date());

    ClientMaster client4 = new ClientMaster();
    client4.setClientName("Client4");
    client4.setDateCreated(new Date());
    client4.setLastUpdated(new Date());

    ClientMasterList.add(client1);
    ClientMasterList.add(client2);
    ClientMasterList.add(client3);
    ClientMasterList.add(client4);      
}

@Test
public void testSave(){     
    for (Iterator iterator = ClientMasterList.iterator(); iterator.hasNext();) {
        ClientMaster ClientMaster = (ClientMaster) iterator.next(); 

        // insert the ClientMaster object 
        clientMasterRepository.save(ClientMaster);

        assertTrue(ClientMaster.getClientName()+" is saved - Id "+ClientMaster.getId(),ClientMaster.getId() > 0);
    }       
}

@Test
public void testUpdate(){
    // get a ClientMaster object from the repository
    ClientMaster clientMasterObj = clientMasterRepository.find(1L);

    // assert if its not null
    assertTrue(!clientMasterObj.getClientName().isEmpty());

    // change the client name 
    clientMasterObj.setClientName("Client1-Changed");

    // update the ClientMaster object
    clientMasterRepository.save(clientMasterObj);

    // assert the value changed id true
    assertEquals("Client1-Changed", clientMasterRepository.find(1L).getClientName());
}

@Test   
public void testDelete(){
    // get a CASClientMaster object from the repository
    ClientMaster clientMasterObjBeforeDel = clientMasterRepository.find(2L);

    // delete the ClientMaster object
    clientMasterRepository.delete(clientMasterObjBeforeDel);

    // get a ClientMaster object from the repository
    ClientMaster clientMasterObjAfterDel = clientMasterRepository.find(2L);

    // get the ClientMaster object ID 
    assertNull(clientMasterObjAfterDel);
}

@Test
public void testFind(){

    // get a ClientMaster object from the repository
    ClientMaster clientMasterObj = clientMasterRepository.find(3L);             

    // compare the id's of passed and retrieved objects.
    assertThat(clientMasterObj.getId(), is(3L));
    assertTrue(clientMasterObj.getId() == 3);       
}

@Test
public void testFindAll(){
    // get all ClientMaster object from the repository 
    List<ClientMaster> ClientMasterList = clientMasterRepository.findAll();             

    // check if it returns all records from DB
    assertTrue(ClientMasterList.size() > 0);
    assertThat(ClientMasterList.size(), is(4));
}

}

当我完全执行所有测试用例时,find & findAll 测试用例将失败,但单独执行时会通过。我是测试框架的新手。让我知道上述测试存储库层的方法是否有任何问题。

更新

即使更新测试用例的行为也很奇怪,因为某些执行工作正常,当我使用 find 方法获取 clientMaster 对象时,它会给出“NullPointerException”错误。

【问题讨论】:

  • 你试过设置方法顺序吗?它可以做到,例如。通过将“@FixMethodOrder(MethodSorters.NAME_ASCENDING)”添加到类中。也许这就是问题所在?

标签: java spring hibernate spring-mvc junit


【解决方案1】:

您的测试不会自动重置持久化数据。有几种方法可以解决或解决这个问题:

1。在测试中添加@Transactional 注解。

事务测试在测试完成后回滚的事务中运行,清除测试保留的任何状态。但是,添加 @Transactional 可能会隐藏一些错误。见this article about it

2。创建一个 @After 方法来清除所有持久更改

这可能维护起来很麻烦,因为您需要跟踪测试持续存在的所有内容。一种稍微复杂但可维护的方法是在运行测试之前转储数据库,然后在每次测试后从该转储中恢复它。

3。以一种即使 DB 已经包含某些内容也不会中断测试的方式实施测试。

例子:

@Test
public void testEntityGetsPersisted() {
    int countBefore = getCurrentCountOfEntities();
    persistNewEntity();
    int countAfter = getCurrentCountOfEntities();
    assertTrue(countAfter == countBefore + 1);
}

【讨论】:

  • ekuusela - 感谢您的快速回复...是的,我知道 abt (at)Transactional annotation..但是为我澄清一些事情...所以数据保留在 (at)Before 注释方法将回滚第一个测试用例或所有测试用例都执行后..在这种情况下,您能否建议更好地测试存储库方法..我检查了许多我发现的链接,但没有一个解决我面临的问题..跨度>
  • docs.spring.io/spring/docs/current/spring-framework-reference/… 。如果一个测试被标记为 (at)Transactional,那么它和在该测试之前调用的 (at)Before 方法将在该事务中运行,并且在测试或之前方法中所做的任何更改都将被回滚。
  • ekusela - 感谢您的建议..我能够通过设置单独的数据库 (HSQL) 进行测试来解决它...并将hibernate.hbm2ddl.auto 属性设置为create-drop 这样对于每个测试执行我将有一个新的数据库...如果我错了请纠正我...因为我已将我的应用程序配置为使用 spring transactions 如果测试用例标记为transactional identity column 值将是回滚后重置为初始值??这是我的问题,身份列值似乎没有重置.....这是真的..还是我错过了什么......
猜你喜欢
  • 2019-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多