找不到为什么 jUnit 测试 return NullPointerException
Cannot find why jUnit test return NullPointerException
我有简单的 Spring 引导 Rest 应用程序什么 returns 来自数据库的用户列表。
应用程序按预期工作,但测试场景因错误而失败。经过长时间的谷歌搜索无法弄清楚为什么?
似乎测试 class 无法访问 userRepository 而不是调用 userRepository.getAllUsers 它调用 AppController.getAllUsers.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
……………………………
Caused by: java.lang.NullPointerException
at com.loan.demo.controller.AppController.getAllUsers(AppController.java:43)
…………………………………………..
这些是我的 class:
LoanAppApplication
@SpringBootApplication
public class LoanAppApplication {
public static void main(String[] args) {
SpringApplication.run(LoanAppApplication.class, args);
}
}
Class User.java
@Entity
@Table(name="USERTABLE")
public class User {
private int id;
@NotNull
private String firstName;
@NotNull
private String lastName;
@NotNull
private String persID;
private int blocked;
private Set<Loan> loans;
public User() {
}
public User(String firstName, String lastName, String persID) {
this.firstName = firstName;
this.lastName = lastName;
this.persID = persID;
}
用户资料库:
@Repository
public interface UserRepository extends JpaRepository<User, Integer>{
public User findById(int Id);
public User findByPersID(String userId);
}
和休息控制器:
@RestController
public class AppController {
@Autowired
UserRepository userRepository;
@GetMapping("/doit")
public String doIt() {
return "Do It";
}
//list all users
@GetMapping("/users")
public List<User> getAllUsers() {
return userRepository.findAll(); // this is line 43 from debuging error log
}
}
并测试class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {LoanAppApplication.class})
public class LoanAppApplicationTests {
private MockMvc mockMvc;
@InjectMocks
private AppController appController;
@Before
public void addData() {
mockMvc = MockMvcBuilders.standaloneSetup(appController)
.build();
}
//First test scenario that return only string works perfectly
@Test
public void testData() throws Exception {
mockMvc.perform(get("/doit")
)
.andExpect(status().isOk())
.andExpect(content().string("Do It"));
}
//but second that should return empty json string fails with exception
@Test
public void testGet() throws Exception {
mockMvc.perform(get("/users")
)
.andExpect(status().isOk())
.andExpect(content().string("Do It")); //this test should fail but not return exception
}
}
您需要模拟您的 userRepository
@Mock
UserRepository userRepository;
所以在@Mock 之后你需要在@Before 中初始化 Mock`s,添加:
MockitoAnnotations.initMocks(this);
然后在代码中设置你想要获得的用户
User user = new User();
when(userRepository.getUsers()).thenReturn(Collections.singletonList(user));
然后检查
verify(userRepository, times(1)).getUsers();
verifyNoMoreInteractions(userRepository);
这是因为您的应用程序上下文不工作
我有简单的 Spring 引导 Rest 应用程序什么 returns 来自数据库的用户列表。 应用程序按预期工作,但测试场景因错误而失败。经过长时间的谷歌搜索无法弄清楚为什么? 似乎测试 class 无法访问 userRepository 而不是调用 userRepository.getAllUsers 它调用 AppController.getAllUsers.
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.NullPointerException
……………………………
Caused by: java.lang.NullPointerException
at com.loan.demo.controller.AppController.getAllUsers(AppController.java:43)
…………………………………………..
这些是我的 class: LoanAppApplication
@SpringBootApplication
public class LoanAppApplication {
public static void main(String[] args) {
SpringApplication.run(LoanAppApplication.class, args);
}
}
Class User.java
@Entity
@Table(name="USERTABLE")
public class User {
private int id;
@NotNull
private String firstName;
@NotNull
private String lastName;
@NotNull
private String persID;
private int blocked;
private Set<Loan> loans;
public User() {
}
public User(String firstName, String lastName, String persID) {
this.firstName = firstName;
this.lastName = lastName;
this.persID = persID;
}
用户资料库:
@Repository
public interface UserRepository extends JpaRepository<User, Integer>{
public User findById(int Id);
public User findByPersID(String userId);
}
和休息控制器:
@RestController
public class AppController {
@Autowired
UserRepository userRepository;
@GetMapping("/doit")
public String doIt() {
return "Do It";
}
//list all users
@GetMapping("/users")
public List<User> getAllUsers() {
return userRepository.findAll(); // this is line 43 from debuging error log
}
}
并测试class:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = {LoanAppApplication.class})
public class LoanAppApplicationTests {
private MockMvc mockMvc;
@InjectMocks
private AppController appController;
@Before
public void addData() {
mockMvc = MockMvcBuilders.standaloneSetup(appController)
.build();
}
//First test scenario that return only string works perfectly
@Test
public void testData() throws Exception {
mockMvc.perform(get("/doit")
)
.andExpect(status().isOk())
.andExpect(content().string("Do It"));
}
//but second that should return empty json string fails with exception
@Test
public void testGet() throws Exception {
mockMvc.perform(get("/users")
)
.andExpect(status().isOk())
.andExpect(content().string("Do It")); //this test should fail but not return exception
}
}
您需要模拟您的 userRepository
@Mock
UserRepository userRepository;
所以在@Mock 之后你需要在@Before 中初始化 Mock`s,添加:
MockitoAnnotations.initMocks(this);
然后在代码中设置你想要获得的用户
User user = new User();
when(userRepository.getUsers()).thenReturn(Collections.singletonList(user));
然后检查
verify(userRepository, times(1)).getUsers();
verifyNoMoreInteractions(userRepository);
这是因为您的应用程序上下文不工作