NULLPOINTEREXCEPTION在Springboot中的Mockit测试类中发生

huangapple go评论67阅读模式
英文:

NULLPOINTEREXCEPTION in Mockit test class in Springboot

问题

我收到了您的请求。以下是您提供的代码的翻译部分:

我在运行为我的Spring Boot应用程序编写的测试类时遇到了NULLPOINTEREXCEPTION我不确定问题是什么我尝试过使用initMocks

**BookControllerTest.java**

package com.example.junitrestapiapplication;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static net.bytebuddy.matcher.ElementMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(MockitoExtension.class)
public class BookControllerTest {
    AutoCloseable openMocks;
    private MockMvc mockMvc;
     ObjectMapper objectMapper= new ObjectMapper();
     ObjectWriter objectWriter= objectMapper.writer();

     @Mock
    private BookRepository bookRepository;

     @InjectMocks
    private BookController bookController;

     Book RECORD_1 = new Book(1L, "Atomic Habits" , "How to build better habits"  , 5);
     Book RECORD_2= new Book(2l, "Thinking Fast and Slow", "How to create good mental models about thinking", 4);
     Book RECORD_3= new Book(3L, "Grokking Algorithms","learn algorithms the fun way",5);

     @Before
    public void setUp() throws Exception {
         MockitoAnnotations.openMocks(this);
         this.mockMvc= MockMvcBuilders.standaloneSetup(bookController).build();

     }

     @Test
    public void getAllRecords_success() throws Exception{
         List<Book> records= new ArrayList<>(Arrays.asList(RECORD_1, RECORD_2, RECORD_3));
         Mockito.when(bookRepository.findAll()).thenReturn(records);
         mockMvc.perform(MockMvcRequestBuilders.
                 get("/book").
                 contentType(MediaType.APPLICATION_JSON)).
                 andExpect(status().isOk()).
                 andExpect(MockMvcResultMatchers.jsonPath("$", hasSize(3))).
                 andExpect((ResultMatcher) jsonPath("$[2].name", is("Grokking Algorithms")));

     }
}

请注意,我已将您提供的代码进行了翻译,但未找到关于"MockMvc: null"的具体信息。如果您需要更多关于这个问题的帮助,请提供更多上下文或详细信息。

英文:

I am getting NULLPOINTEREXCEPTION on running this test class that I am writing for my springboot application. I am not sure what the problem is, I tried using initMocks too.

BookControllerTest.java

package com.example.junitrestapiapplication;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.bytebuddy.matcher.ElementMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(MockitoExtension.class)
public class BookControllerTest {
AutoCloseable openMocks;
private MockMvc mockMvc;
ObjectMapper objectMapper= new ObjectMapper();
ObjectWriter objectWriter= objectMapper.writer();
@Mock
private BookRepository bookRepository;
@InjectMocks
private BookController bookController;
Book RECORD_1 = new Book(1L, "Atomic Habits" , "How to build better habits"  , 5);
Book RECORD_2= new Book(2l, "Thinking Fast and Slow", "How to create good mental models about thinking", 4);
Book RECORD_3= new Book(3L, "Grokking Algorithms","learn algorithms the fun way",5);
@Before
public void setUp() throws Exception {
MockitoAnnotations.openMocks(this);
this.mockMvc= MockMvcBuilders.standaloneSetup(bookController).build();
}
@Test
public void getAllRecords_success() throws Exception{
List<Book> records= new ArrayList<>(Arrays.asList(RECORD_1, RECORD_2, RECORD_3));
Mockito.when(bookRepository.findAll()).thenReturn(records);
mockMvc.perform(MockMvcRequestBuilders.
get("/book").
contentType(MediaType.APPLICATION_JSON)).
andExpect(status().isOk()).
andExpect(MockMvcResultMatchers.jsonPath("$", hasSize(3))).
andExpect((ResultMatcher) jsonPath("$[2].name", is("Grokking Algorithms")));
}
}

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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.12</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example</groupId>
<artifactId>junit-rest-api-application</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>junit-rest-api-application</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.junit.platform</groupId>
<artifactId>junit-platform-launcher</artifactId>
<scope>test</scope>
</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-devtools</artifactId>
<scope>runtime</scope>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.apache.derby</groupId>
<artifactId>derby</artifactId>
<version>10.16.1.1</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-bom</artifactId>
<version>2.15.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.inject</groupId>
<artifactId>javax.inject</artifactId>
<version>1</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>
</project>

BookRepository.java

package com.example.junitrestapiapplication;
import org.springframework.data.domain.Example;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.query.FluentQuery;
import org.springframework.stereotype.Repository;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
@Repository
public class BookRepository implements JpaRepository<Book, Long> {
@Override
public List<Book> findAll() {
return null;
}
@Override
public List<Book> findAll(Sort sort) {
return null;
}
@Override
public Page<Book> findAll(Pageable pageable) {
return null;
}
@Override
public List<Book> findAllById(Iterable<Long> longs) {
return null;
}
@Override
public long count() {
return 0;
}
@Override
public void deleteById(Long aLong) {
}
@Override
public void delete(Book entity) {
}
@Override
public void deleteAllById(Iterable<? extends Long> longs) {
}
@Override
public void deleteAll(Iterable<? extends Book> entities) {
}
@Override
public void deleteAll() {
}
@Override
public <S extends Book> S save(S entity) {
return null;
}
@Override
public <S extends Book> List<S> saveAll(Iterable<S> entities) {
return null;
}
@Override
public Optional<Book> findById(Long aLong) {
return Optional.empty();
}
@Override
public boolean existsById(Long aLong) {
return false;
}
@Override
public void flush() {
}
@Override
public <S extends Book> S saveAndFlush(S entity) {
return null;
}
@Override
public <S extends Book> List<S> saveAllAndFlush(Iterable<S> entities) {
return null;
}
@Override
public void deleteAllInBatch(Iterable<Book> entities) {
}
@Override
public void deleteAllByIdInBatch(Iterable<Long> longs) {
}
@Override
public void deleteAllInBatch() {
}
@Override
public Book getOne(Long aLong) {
return null;
}
@Override
public Book getById(Long aLong) {
return null;
}
@Override
public Book getReferenceById(Long aLong) {
return null;
}
@Override
public <S extends Book> Optional<S> findOne(Example<S> example) {
return Optional.empty();
}
@Override
public <S extends Book> List<S> findAll(Example<S> example) {
return null;
}
@Override
public <S extends Book> List<S> findAll(Example<S> example, Sort sort) {
return null;
}
@Override
public <S extends Book> Page<S> findAll(Example<S> example, Pageable pageable) {
return null;
}
@Override
public <S extends Book> long count(Example<S> example) {
return 0;
}
@Override
public <S extends Book> boolean exists(Example<S> example) {
return false;
}
@Override
public <S extends Book, R> R findBy(Example<S> example, Function<FluentQuery.FetchableFluentQuery<S>, R> queryFunction) {
return null;
}
}

BookController.java

package com.example.junitrestapiapplication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
import java.util.Optional;
@RestController
@RequestMapping(value="/book")
public class BookController {
@Autowired
BookRepository bookRepository;
@GetMapping
public List<Book> getAllBookRecords()
{
return bookRepository.findAll();
}
@GetMapping(value = "{bookId}")
public Book getBookbyID(@PathVariable(value = "bookId") Long bookId)
{
return bookRepository.findById(bookId).get();
}
@PostMapping
public Book createBookRecord(@RequestBody   Book bookRecord)
{
return bookRepository.save(bookRecord);
}
@PutMapping
public Book updateBookRecord(@RequestBody   Book bookRecord ) throws  Exception {
if(bookRecord==null || bookRecord.getBookId()==null)
{
throw new Exception("Book Record or ID must not be null");
}
Optional<Book> optionalBook=bookRepository.findById(bookRecord.getBookId());
if(!optionalBook.isPresent())throw new Exception("Book with ID: "+bookRecord.getBookId()+" does not exist");
Book existingBookRecord=optionalBook.get();
existingBookRecord.setName(bookRecord.getName());
existingBookRecord.setSummary(bookRecord.getSummary());
existingBookRecord.setRating(bookRecord.getRating());
return bookRepository.save(existingBookRecord);
}
}

Book.java

package com.example.junitrestapiapplication;
import com.sun.istack.NotNull;
import lombok.*;
import javax.persistence.*;
@Entity
@Table(name="book_record")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long bookId;
@NonNull
private String name;
@NonNull
private String summary;
private int rating;
}

I am receiving MockMvc: null on debugging. I have tried changing initialization of Mock.

答案1

得分: 0

@BeforeEach@Before 的主要区别是它们所属的JUnit版本。@BeforeEach 用于JUnit 5(JUnit Jupiter),比JUnit 4中的 @Before 提供更多的灵活性和改进的功能。

如果您正在使用JUnit 5,建议在设置操作中使用 @BeforeEach。然而,如果您正在使用JUnit 4,应该使用 @Before

尝试替换您的导入并使用正确的方法:

将以下导入替换为:

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;

类:

package com.example.junitrestapiapplication;

import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static net.bytebuddy.matcher.ElementMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;

@ExtendWith(MockitoExtension.class)
public class BookControllerTest {
    AutoCloseable openMocks;
    private MockMvc mockMvc;
     ObjectMapper objectMapper= new ObjectMapper();
     ObjectWriter objectWriter= objectMapper.writer();

     @Mock
    private BookRepository bookRepository;

     @InjectMocks
    private BookController bookController;

     Book RECORD_1 = new Book(1L, "Atomic Habits" , "How to build better habits"  , 5);
     Book RECORD_2= new Book(2l, "Thinking Fast and Slow", "How to create good mental models about thinking", 4);
     Book RECORD_3= new Book(3L, "Grokking Algorithms","learn algorithms the fun way",5);

     @BeforeEach
    public void setUp() throws Exception {
         MockitoAnnotations.openMocks(this);
         this.mockMvc= MockMvcBuilders.standaloneSetup(bookController).build();

     }

     @Test
    public void getAllRecords_success() throws Exception{
         List<Book> records= new ArrayList<>(Arrays.asList(RECORD_1, RECORD_2, RECORD_3));
         Mockito.when(bookRepository.findAll()).thenReturn(records);
         mockMvc.perform(MockMvcRequestBuilders.
                 get("/book").
                 contentType(MediaType.APPLICATION_JSON)).
                 andExpect(status().isOk()).
                 andExpect(MockMvcResultMatchers.jsonPath("$", hasSize(3))).
                 andExpect(jsonPath("$[2].name", is("Grokking Algorithms")));

     }
}

注意:上述代码已经将注释中的HTML实体字符(如 &quot;)替换为了普通文本。

英文:

The main difference between @BeforeEach and @Before is the version of JUnit they belong to. @BeforeEach is used in JUnit 5 (JUnit Jupiter) and offers more flexibility and improved features than @Before in JUnit 4.

If you're using JUnit 5, using @BeforeEach for setup operations is recommended. However, if you're using JUnit 4, you should use @Before.

Try replacing your imports and use correct method:

Replace the following imports

import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;

With

import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.junit.jupiter.MockitoExtension;

Class

package com.example.junitrestapiapplication;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.ObjectWriter;
import org.junit.Before;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import org.mockito.junit.jupiter.MockitoExtension;
import org.springframework.http.MediaType;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultMatcher;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import static net.bytebuddy.matcher.ElementMatchers.is;
import static org.hamcrest.Matchers.hasSize;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
@ExtendWith(MockitoExtension.class)
public class BookControllerTest {
AutoCloseable openMocks;
private MockMvc mockMvc;
ObjectMapper objectMapper= new ObjectMapper();
ObjectWriter objectWriter= objectMapper.writer();
@Mock
private BookRepository bookRepository;
@InjectMocks
private BookController bookController;
Book RECORD_1 = new Book(1L, &quot;Atomic Habits&quot; , &quot;How to build better habits&quot;  , 5);
Book RECORD_2= new Book(2l, &quot;Thinking Fast and Slow&quot;, &quot;How to create good mental models about thinking&quot;, 4);
Book RECORD_3= new Book(3L, &quot;Grokking Algorithms&quot;,&quot;learn algorithms the fun way&quot;,5);
@BeforeEach
public void setUp() throws Exception {
MockitoAnnotations.openMocks(this);
this.mockMvc= MockMvcBuilders.standaloneSetup(bookController).build();
}
@Test
public void getAllRecords_success() throws Exception{
List&lt;Book&gt; records= new ArrayList&lt;&gt;(Arrays.asList(RECORD_1, RECORD_2, RECORD_3));
Mockito.when(bookRepository.findAll()).thenReturn(records);
mockMvc.perform(MockMvcRequestBuilders.
get(&quot;/book&quot;).
contentType(MediaType.APPLICATION_JSON)).
andExpect(status().isOk()).
andExpect(MockMvcResultMatchers.jsonPath(&quot;$&quot;, hasSize(3))).
andExpect((ResultMatcher) jsonPath(&quot;$[2].name&quot;, is(&quot;Grokking Algorithms&quot;)));
}
}

huangapple
  • 本文由 发表于 2023年6月22日 00:03:44
  • 转载请务必保留本文链接:https://go.coder-hub.com/76525190.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定