首页 > 解决方案 > Junit5 jpa存储库空指针异常

问题描述

我正在尝试测试存储库。唉,当我尝试测试时,我不断收到同样的错误。错误如下:

java.lang.NullPointerException
    at com.changing.springboot.repository.TemplateRepositoryTest.should_return_templateName_when_call_findByTemplateName(TemplateRepositoryTest.java:22)
    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:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
    at org.junit.vintage.engine.execution.RunnerExecutor.execute(RunnerExecutor.java:43)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:183)
    at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
    at java.util.Iterator.forEachRemaining(Iterator.java:116)
    at java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1801)
    at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482)
    at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472)
    at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:150)
    at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:173)
    at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
    at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:485)
    at org.junit.vintage.engine.VintageTestEngine.executeAllChildren(VintageTestEngine.java:82)
    at org.junit.vintage.engine.VintageTestEngine.execute(VintageTestEngine.java:73)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:229)
    at org.junit.platform.launcher.core.DefaultLauncher.lambda$execute$6(DefaultLauncher.java:197)
    at org.junit.platform.launcher.core.DefaultLauncher.withInterceptedStreams(DefaultLauncher.java:211)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:191)
    at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:137)
    at org.eclipse.jdt.internal.junit5.runner.JUnit5TestReference.run(JUnit5TestReference.java:89)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:41)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:541)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:763)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:463)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:209)

这是我的 TemplateRepositoryTest.class:

package com.changing.springboot.repository;

import java.util.List;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;

import com.changing.springboot.model.TemplateModel;

@DataJpaTest
@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.AUTO_CONFIGURED)
public class TemplateRepositoryTest {
     
     @Autowired
     TemplateRepository templateRepository;
     
     @Test
     public void should_return_templateName_when_call_findByTemplateName() {
         
         List<TemplateModel> list = templateRepository.findAll();
     }
}

这是我的 TemplateRepository.class:

package com.changing.springboot.repository;

import java.util.Date;
import java.util.List;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import com.changing.springboot.model.TemplateModel;

@Repository
public interface TemplateRepository extends JpaRepository<TemplateModel, Integer> {
    List<TemplateModel> findAll();

    TemplateModel findByTemplateName(String templateName);

    TemplateModel findByTemplateCusUid(String templateCusUid);

    Page<TemplateModel> findAllByTemplateCreateTimeBetween(Date begin, Date after, Pageable pageable);

    Page<TemplateModel> findAllByTemplateNameAndTemplateCreateTimeBetween(String templateName, Date begin, Date after,
            Pageable pageable);

    Page<TemplateModel> findAllByTemplateCusUidAndTemplateCreateTimeBetween(String templateCusUid, Date begin,
            Date after, Pageable pageable);

    Page<TemplateModel> findAllByTemplateNameAndTemplateCusUidAndTemplateCreateTimeBetween(String templateName,
            String templateCusUid, Date begin, Date after, Pageable pageable);
}

这是我的 TemplateModel.class:

package com.changing.springboot.model;

import lombok.*;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
import org.hibernate.annotations.GenericGenerator;

import javax.persistence.*;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

@Entity
@Table(name = "cg_template")
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class TemplateModel{
    
    @Id
    @GeneratedValue(generator = "id_Sequence")
    @GenericGenerator(name = "id_Sequence", strategy = "native")
    @Column(name = "template_id")
    private Integer templateId;

    @ManyToOne
    @JoinColumn(name = "template_creator_account_id")
    private AccountModel accountModel;

    @ManyToOne
    @JoinColumn(name = "template_group_id")
    private FormGroupModel formGroupModel;

    @OneToMany(mappedBy = "template", orphanRemoval = false, fetch = FetchType.LAZY)
    @Cascade(value = CascadeType.SAVE_UPDATE)
    @OrderBy("docId ASC")
    private List<DocModel> cgDoc = new ArrayList<DocModel>();

    @Column(name = "template_name")
    private String templateName;

    @Column(name = "template_desc")
    private String templateDesc;

    @Column(name = "template_create_time")
    private Date templateCreateTime;

    @Column(name = "template_uid")
    private String templateUid;

    @Column(name = "template_cus_uid")
    private String templateCusUid;

    @Column(name = "template_status")
    private Integer templateStatus;

    @Column(name = "template_expire_days")
    private Integer templateExpireDays;

    @Column(name = "template_sign_video_flag")
    private Integer signVideoFlag;

    @Column(name = "template_check_require_item")
    private Integer checkRequiredBeforeSign;
    
    @Column(name = "template_check_required_before_upload")
    private Integer checkRequiredBeforeUpload;

    
    public TemplateModel(AccountModel accountModel, FormGroupModel formGroupModel, String templateName, String templateDesc,
            Date templateCreateTime, String templateUid, String templateCusUid, Integer templateStatus,
            Integer templateExpireDays,Integer signVideoFlag, Integer checkRequiredBeforeSign, Integer checkRequiredBeforeUpload) {
        super();
        this.accountModel = accountModel;
        this.formGroupModel = formGroupModel;
        this.templateName = templateName;
        this.templateDesc = templateDesc;
        this.templateCreateTime = templateCreateTime;
        this.templateUid = templateUid;
        this.templateCusUid = templateCusUid;
        this.templateStatus = templateStatus;
        this.templateExpireDays = templateExpireDays;
        this.signVideoFlag=signVideoFlag;
        this.checkRequiredBeforeSign = checkRequiredBeforeSign;
        this.checkRequiredBeforeUpload = checkRequiredBeforeUpload;
    }
}

这个问题发生在 List list = templateRepository.findAll();

我在 application.yml 中的数据库连接字符串。我不知道这个问题与连接数据库或存储库错误有关。如果问题是数据库,我如何通过单元测试连接到数据库?我想连接真正的数据库,而不是 H2。

如果您能帮助或指出正确的方向,我将不胜感激。谢谢

标签: javaspring-bootjunit5

解决方案


@DataJpaTest上的 Spring 文档

使用此注解将禁用完全自动配置,而是仅应用与 JPA 测试相关的配置。

您的存储库为空。在给定的测试设置中,Spring 对TemplateRepository. 因此,您需要做的是提供一个应用程序上下文,以便 Spring 可以注入托管依赖项。

当您使用 JUnit5 时,请尝试向您的测试添加另一个注释@ExtendWith(SpringExtension.class)以启用 Spring 应用程序上下文。


推荐阅读