【问题标题】:Mockito Test With java.lang.NullPointerException使用 java.lang.NullPointerException 进行 Mockito 测试
【发布时间】:2019-04-27 10:53:33
【问题描述】:

我使用 Junit 4 和 Mockito 创建了一个 Spring Boot 2 应用程序。当我测试一些方法时。会有这样的例外:

java.lang.NullPointerException 在 com.xxx.service.SurveyServiceTest.getSurveyList(SurveyServiceTest.java:41) 在 sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 在 sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 在 sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 在 java.lang.reflect.Method.invoke(Method.java:498) 在 org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 在 org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 在 org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 在 org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 在 org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 在 org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 在 org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 在 org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 在 org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 在 org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 在 org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 在 org.junit.runners.ParentRunner.run(ParentRunner.java:363) 在 org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79) 在 org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85) 在 org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39) 在 org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163) 在 org.junit.runner.JUnitCore.run(JUnitCore.java:137) 在 com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) 在 com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47) 在 com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) 在 com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

这是我的测试代码

@RunWith(MockitoJUnitRunner.class)
public class SurveyServiceTest {

    @MockBean
    SurveyRepository repostory;

    @InjectMocks
    SurveyService service;

    @Test
    public void getSurveyList() {
        when(repostory.findAll()).thenReturn(Arrays.asList( new Survey(new Long(1),101,"Test1"),
                new Survey(new Long(2),102,"Test2")  ));
        assertTrue(service.getSurveyList().size() >0);
    }
}

SuveryService.java

@Service
public class SurveyService {
    @Autowired
    private SurveyRepository repostory;

    public List<Survey> getSurveyList() {
        return repostory.findAll();
    }

    public Optional<Survey> getSurveyById() {
        return repostory.findById((long) 1);
    }

    public Survey add() {
        Survey survey = new Survey();
        survey.setSurveyID(1);
        survey.setSurveyContent("ddddd");

        return repostory.save(survey);
    }

    public Survey update() {
        Survey survey = new Survey();
        survey.setSurveyID(1);
        survey.setSurveyContent("gggg1");
        return repostory.save(survey);
    }

    public void delete() {
        repostory.deleteById((long) 1);
    }

    public List<Survey> findBySurveyContent() {
        return repostory.findBySurveyContent("gggg1");
    }

    public int updateBySurveyId(){
        return repostory.updateBySurveyId("hhhhhh", 1);
    }
}

SurveyRepository.java

    public interface SurveyRepository  extends JpaRepository<Survey, Long> {

    public List<Survey> findBySurveyContent(String surveyContent);

    @Query(value = "update XXX_DATA.SURVEYS set SURVEYCONTENT=? where SURVEYID=?",nativeQuery = true)  
    @Modifying
    @Transactional
    public int updateBySurveyId(String surveyContent,int surveyId);
}

Survey.java

@Entity
@Table(name="SURVEYS", schema="XXX_DATA")
public class Survey{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID")  
    private Long id; 

    @Column(name = "SURVEYID")  
    private Integer surveyID;

    @Column(name = "SURVEYCONTENT")  
    private String surveyContent;

    public Survey(){

    }

    public Survey(Long id,Integer surveyID,String surveyContent){
        this.id = id;
        this.surveyID = surveyID;
        this.surveyContent = surveyContent;
    }

    public Long getId() {
        return id;
    }

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

    public Integer getSurveyID() {
        return surveyID;
    }

    public void setSurveyID(Integer surveyID) {
        this.surveyID = surveyID;
    }

    public String getSurveyContent() {
        return surveyContent;
    }

    public void setSurveyContent(String surveyContent) {
        this.surveyContent = surveyContent;
    }
}

POM.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<groupId>com.xxx.test</groupId>
<artifactId>xxx-service</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>

<name>xxx-service</name>
<description>XXX Service</description>

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.1.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    <java.version>1.8</java.version>
</properties>

<repositories>
    <repository>
        <id>maven-repository</id>
        <url>file:///${project.basedir}/maven-repository</url>
    </repository>
    <repository>
        <id>com.ibm.db2.jcc</id>
        <url>https://artifacts.alfresco.com/nexus/content/repositories/public/</url>
    </repository>
</repositories>

<dependencies>
    <dependency>
        <groupId>com.ibm.db2.jcc</groupId>
        <artifactId>db2jcc4</artifactId>
        <version>10.1</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.ibm.watson.developer_cloud</groupId>
        <artifactId>java-sdk</artifactId>
        <version>5.1.1</version>
    </dependency>
    <dependency>
        <groupId>org.apache.httpcomponents</groupId>
        <artifactId>httpclient</artifactId>
     </dependency>
     <dependency>
        <groupId>com.ibm.swat.password</groupId>
        <artifactId>cwa2</artifactId>
        <version>2.3.5.3</version>
      </dependency>
      <dependency>
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml</artifactId>
        <version>3.15</version>
      </dependency> 
      <dependency> 
        <groupId>org.apache.poi</groupId>
        <artifactId>poi-ooxml-schemas</artifactId>
        <version>3.15</version>
      </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <configuration>
                  <skip>true</skip>
                </configuration>
        </plugin>
    </plugins>
</build>

我参考了这篇文章Mockito NullPointerException,但问题依然存在。 如有任何帮助,我们将不胜感激。

【问题讨论】:

    标签: spring-boot junit nullpointerexception mockito


    【解决方案1】:

    为了扩展上述答案,由于@MockBean 是一个弹簧注释,您可以使用以下代码作为替代方案。 @MockBean 用于将模拟对象添加到 Spring 应用程序上下文中。模拟将替换应用程序上下文中任何现有的相同类型的 bean。所以它是@Mock 和@InjectMock 的一种功能。此外,如果您不遵循 JUnit 5,则需要将 @RunWith(SpringRunner.class) 替换为 @ExtendWith(SpringExtention.class)

    @RunWith(SpringRunner.class)
    public class SurveyServiceTest {
    
        @MockBean
        SurveyRepository repostory;
    
        @Test
        public void getSurveyList() {
            when(repostory.findAll()).thenReturn(Arrays.asList( new Survey(new 
             Long(1),101,"Test1"),
                new Survey(new Long(2),102,"Test2")  ));
             assertTrue(service.getSurveyList().size() >0);
    }
    

    }

    【讨论】:

      【解决方案2】:

      你应该这样做:

      @RunWith(MockitoJUnitRunner.class)
      public class SurveyServiceTest {
      
          @Mock// and not MockBean
          SurveyRepository repostory;
      
          @InjectMocks
          SurveyService service;
      
          @Test
          public void getSurveyList() {
              when(repostory.findAll()).thenReturn(Arrays.asList( new Survey(new Long(1),101,"Test1"),
                      new Survey(new Long(2),102,"Test2")  ));
              assertTrue(service.getSurveyList().size() >0);
          }
      }
      

      【讨论】:

        【解决方案3】:

        @MockBean 是一个 Spring 注解,只有在创建 Spring boot 集成测试时才有效,使用 SpringRunner 运行。

        您在这里有一个单元测试,使用MockitoJUnitRunner 运行,您只希望 Mockito 创建您的模拟存储库。正确的注解是@Mock

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-03-10
          • 1970-01-01
          • 2020-02-22
          相关资源
          最近更新 更多