JUnit Test case : java.lang.NullPointerException



我正在尝试为Repository编写JUnit测试用例。我在内存数据库依赖项中添加了H2,还为 h2 数据库设置了配置。但我越来越null pointer exception.任何人都可以告诉我我在代码中做错了什么吗?

部门

@Entity
@Table(name = "department")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Department implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "department_seq_generator")
@SequenceGenerator(name = "department_seq_generator", sequenceName = "department_seq")
@Column(name = "ndept_id")
public Integer nDeptId;
@Column(name = "sdept_name")
public String sDeptName;
@Column(name = "ninst_id")
public Integer nInstId;
@Column(name = "bis_locked")
public Boolean bIsLocked;
@Column(name = "sclient_dept_id")
public String sClientDeptId;
@Column(name = "nsurvey_method_id")
public Integer nSurveyMethodId;
@Column(name = "bis_jointuse")
public Boolean bIsJointuse;
@Column(name = "ntemp_dept_id")
public Integer nTempDeptId;
@Column(name = "balternate_jointuse_percentage")
public Boolean bAlternateJointusePercentage;
@Column(name = "ndiv_id")
public Integer nDivId;
// Getter and Setter

DepaertmentRepository

@Repository
public interface DepaertmentRepository extends JpaRepository<Department, Integer> {
Department findByNDeptId(Integer nDeptId);
}

部门存储库测试

@RunWith(SpringRunner.class)
@DataJpaTest
public class DepartmentRepositoryTest { 
@Autowired
private static DepaertmentRepository depRepo; 
@Autowired
public TestEntityManager em;        
@Test
public void TestFindById() {
Department dep = new Department();
dep.setnDeptId(1);
System.out.println(dep.getnDeptId());// here i am getting 1
Department saveInDB = em.merge(dep);        
System.out.println(saveInDB.getnDeptId());// here i am getting 50
Department getFromDB = depRepo.findByNDeptId(saveInDB.getnDeptId());
System.out.println(getFromDB.getnDeptId());// here i am getting 50
assertThat(getFromDB).isEqualTo(saveInDB);
}       
}

Stack Trace for PersistenceException

javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.spacestudy.model.Department
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1692)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1602)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1608)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1152)
at org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager.persist(TestEntityManager.java:93)
at com.spacestudy.DepartmentRepositoryTest.TestFindById(DepartmentRepositoryTest.java:36)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
Caused by: org.hibernate.PersistentObjectException: detached entity passed to persist: com.spacestudy.model.Department
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:124)
at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:58)
at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:775)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:748)
at org.hibernate.internal.SessionImpl.persist(SessionImpl.java:753)
at org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:1146)
... 31 more

使用上面的代码测试用例成功运行,没有空指针异常。但是当我在每一行放置检查点时,我观察到我在这里合并数据库后nDeptId1保存saveInDB.getnDeptId()我得到了50.我不明白为什么它来了 50 而不是 1;

这可能会有所帮助!

问题就在这里:Department found = depRepo.findByNDeptId(1);您希望返回数据而不是 null。

默认情况下,使用@DataJpaTest批注的测试将使用嵌入式内存数据库(替换任何显式或通常自动配置的数据源(。

因此,根据您在问题中提供的内容:

  • 检查您是否有预期的测试数据。您需要在内存数据库或您使用的数据库中拥有 ID = 1 的记录。
  • 如果没有,则需要先准备一些测试数据(例如,在您的测试类中添加@BeforeClass方法,您可以在运行测试之前插入一些测试数据(
  • 也许当您使用实体管理器(此行entityManager.merge(dep);(创建测试数据时,它会将其保存到另一个数据库?不是你正在阅读的那个?无论如何,最好在运行测试之前创建测试。

例如

@BeforeClass
public static void init() {
// you could try instead of this to use your Repository to create test data
Department dep = new Department();
dep.setnDeptId(1);
// entityManager.merge(dep);
yourRepo.save(dep);    
}

更新:

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "department_seq_generator")
@SequenceGenerator(name = "department_seq_generator", sequenceName = "department_seq")
@Column(name = "ndept_id")
public Integer nDeptId;

根据此代码,数据库中有一个序列,负责为新记录创建 ID。

基本上是它的工作原理:当您保存新记录时,会调用类似sequence get me next id的内容,您将获得 ID。

这就是为什么即使您为ID设置了一些东西(您不应该做什么(,您也会得到一个完全不同的数字!

因此,这就是您可以修改测试的方法:

@Test
public void TestFindById() {
Department dep = new Department();
// you can set some fields here but not ID
// this is saved entity, it means it has an ID assigned by the database
Department saveInDB = em.merge(dep);        
// that is what you need
final Integer newRecordID = getFromDB.getnDeptId();
// test your repository or what you need
Department getFromDB = depRepo.findByNDeptId(newRecordID);

// all asserts that you need
assertThat(getFromDB).isEqualTo(saveInDB);
} 

相关内容

最新更新