gpt4 book ai didi

java - 为什么我的 Spring Boot 服务测试返回 NullPointerException?

转载 作者:行者123 更新时间:2023-12-02 10:58:05 24 4
gpt4 key购买 nike

最近我一直在尝试测试我的 Spring Boo(2.0.3) 服务,但我一直收到 NullPointerException。 userDAOImpl实现userDAO接口(interface),

这里是serviceImpl类,它实现了Service接口(interface):

import app.clothapp.DAO.UserDAO;
import app.clothapp.Model.User;
import app.clothapp.Service.UserService;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
Logger logger = LogManager.getLogger("UserServiceImplLogger");


@Autowired
private UserDAO userDao;



@Override
@Transactional
public void createUser(User user) {
logger.debug("Creating an user " + UserServiceImpl.class.getName());
userDao.addUser(user);
}

@Override
public void deleteUserById(int id) {
logger.debug("Deleting an user " + UserServiceImpl.class.getName());
userDao.deleteUserById(id);
}

@Override
public List<User> getUsersByEmail(String email) {
logger.debug("Getting a list of users by email" + UserServiceImpl.class.getName());
return userDao.findUsersByEmail(email);
}

@Override
public void changeUserPassword(User user, String newPassword) {
logger.debug("Changing a user's password " + UserServiceImpl.class.getName());
userDao.changeUserPassword(user, newPassword);
}

@Override
public void changeUserFirstName(User user, String firstName) {
logger.debug("Changing an user's first name" + UserServiceImpl.class.getName());
userDao.changeUserFirstname(user, firstName);
}

@Override
public void changeUserLastname(User user, String lastname) {
logger.debug("Changing an user's last name" + UserServiceImpl.class.getName());
userDao.changeUserLastname(user, lastname);
}

@Override
public void changeUserEmail(User user, String email) {
logger.debug("Changing an user's email" + UserServiceImpl.class.getName());
userDao.changeUserEmail(user, email);
}

@Override
public List<User> findAllUsers() {
logger.debug("Finding all users" + UserServiceImpl.class.getName());
return userDao.findAllUsers();
}
}

这是我的 UserDAOImpl。

import app.clothapp.DAO.UserDAO;
import app.clothapp.Model.User;
import app.clothapp.Model.User.UserFactory;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;

//import static org.apache.logging.log4j.Level.ALL;
//import static org.apache.logging.log4j.Level.DEBUG;
//import static org.apache.logging.log4j.Level.WARN;




@Repository
@Qualifier("UserDAO")
public class UserDAOImpl implements UserDAO {


@Autowired
JdbcTemplate jdbcTemplate;
Logger logger = LogManager.getLogger("Log");



@Override
public void addUser(User user) {
logger.debug(UserDAOImpl.class.getName() + ": addUser() creating user");
if (findUsersByEmail(user.getEmail()).isEmpty() == false) {
logger.debug(UserDAOImpl.class.getName() + ":addUser() denied user creation because of email duplicate!");
} else {
jdbcTemplate.update("INSERT INTO User(firstName, lastName, Email, Password) VALUES (?, ?, ?, ?) ", user.getFirstname(), user.getLastname(), user.getEmail(), user.getPassword());
logger.debug(UserDAOImpl.class.getName() + ": addUser() User created!");

}

}

@Override
public void changeUserPassword(User user, String password) {
jdbcTemplate.update("UPDATE User SET Password = ? WHERE Id = ?", password, user.getId());
logger.debug(UserDAOImpl.class.getName() + "User changed password. ");
}

@Override
public void changeUserFirstname(User user, String firstName) {
jdbcTemplate.update("UPDATE User SET Firstname = ? WHERE Id = ?", firstName, user.getId());
logger.debug(UserDAOImpl.class.getName() + "User changed the first name.");
}

@Override
public void changeUserLastname(User user, String lastname) {
jdbcTemplate.update("UPDATE User SET Lastname = ? Where Id = ?", lastname, user.getId());
logger.debug(UserDAOImpl.class.getName() + "User changed last name.");
}

@Override
public void changeUserEmail(User user, String email) throws RuntimeException {
if (findUsersByEmail(email).isEmpty() == false) {
System.out.println(UserDAOImpl.class.getName() + "There is already a user within the database that has that email.");
throw new RuntimeException(UserDAOImpl.class.getName() + "There is already a user within the database that has that email.");
} else {
jdbcTemplate.update("UPDATE User SET Email = ? Where Id = ?", email, user.getId());
logger.debug(UserDAOImpl.class.getName() + new StringBuilder().append("User").append(user.getFirstname()).append("email was changed.").toString());
}
}

@Override
public void deleteUserById(int id) {
logger.debug("Deleted user with user ID" + id + UserDAOImpl.class.getName());
jdbcTemplate.update("DELETE from User WHERE Id = ?", id);
}

@Override
public List<User> findUsersByEmail(String email) {
logger.debug(UserDAOImpl.class.getName() + "found users by email using foundUsersByEmail()");
return jdbcTemplate.query("SELECT * FROM User where Email = ?", new UserRowMapper(), email);
}


@Override
public List<User> findAllUsers() {
logger.debug(UserDAOImpl.class.getName() + "found all Users");
return jdbcTemplate.query("SELECT * FROM User", new UserRowMapper());

}

public class UserRowMapper implements RowMapper<User> {
public User mapRow(ResultSet resultSet, int rowNumber) throws SQLException {
UserFactory userFactory = new User.UserFactory()
.setId(resultSet.getInt("id"))
.setFirstname(resultSet.getString("Firstname"))
.setLastname(resultSet.getString("Lastname"))
.setPassword(resultSet.getString("Password"))
.setEmail(resultSet.getString("Email"));

User user = userFactory.build();
return user;
}
}
}

这是我的 JUnit 5 Spring Boot 测试:

@RunWith(SpringJUnit4ClassRunner.class)

class UserServiceTest {

User user = new User.UserFactory().setFirstname("Firs")
.setLastname("Las")
.setEmail("email@email.com")
.setPassword("paaaaaaa")
.build();

@Mock
private JdbcTemplate jdbcTemplate = new JdbcTemplate();

@InjectMocks
private UserServiceImpl userService;


@Mock
private UserDAO userDAO;

@BeforeEach
void setUp() {

MockitoAnnotations.initMocks(this.getClass());



}

@Test
void createUser() {
Mockito.doNothing().when(userDAO).addUser(user);
userService.createUser(user);

Mockito.when(userService.findAllUsers().get(0)).thenReturn(user);

assertEquals(userService.findAllUsers().get(0), user);
}

@Test
void deleteUserById() {
}

@Test
void getUsersByEmail() {
}

@Test
void changeUserPassword() {
}

@Test
void changeUserFirstName() {
}

@Test
void changeUserLastname() {
}

@Test
void changeUserEmail() {
}

@Test
void findAllUsers() {
}

}

如您所见,我利用 UserFactory 创建一个用户,模拟 jdbcTemplate 和 userDAOImpl,然后将它们注入(inject)到 UserServiceImpl() 中。然后在 createUser() 测试中,我使用该服务创建用户,并设置 Mockito.when,并测试该用户是否存在于数据库中。

但是,我收到 NullPointerException,尽管我不确定原因。有人可以给我提示吗?

编辑:我现在收到 NullInsteadOfMock 错误,我必须实例化 UserDAO 对象,但 UserDAO 是一个接口(interface)!

org.mockito.exceptions.misusing.NullInsteadOfMockException: 
Argument passed to when() is null!
Example of correct stubbing:
doThrow(new RuntimeException()).when(mock).someMethod();
Also, if you use @Mock annotation don't miss initMocks()

at app.clothapp.ServiceImpl.UserServiceTest.createUser(UserServiceTest.java:55)
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.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:513)
at org.junit.jupiter.engine.execution.ExecutableInvoker.invoke(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.lambda$invokeTestMethod$6(TestMethodTestDescriptor.java:170)
at org.junit.jupiter.engine.execution.ThrowableCollector.execute(ThrowableCollector.java:40)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.invokeTestMethod(TestMethodTestDescriptor.java:166)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:113)
at org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor.execute(TestMethodTestDescriptor.java:58)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:113)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
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:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$2(HierarchicalTestExecutor.java:121)
at java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:175)
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:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:418)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.lambda$executeRecursively$3(HierarchicalTestExecutor.java:121)
at org.junit.platform.engine.support.hierarchical.SingleTestExecutor.executeSafely(SingleTestExecutor.java:66)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.executeRecursively(HierarchicalTestExecutor.java:108)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor$NodeExecutor.execute(HierarchicalTestExecutor.java:79)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestExecutor.execute(HierarchicalTestExecutor.java:55)
at org.junit.platform.engine.support.hierarchical.HierarchicalTestEngine.execute(HierarchicalTestEngine.java:43)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:170)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:154)
at org.junit.platform.launcher.core.DefaultLauncher.execute(DefaultLauncher.java:90)
at com.intellij.junit5.JUnit5IdeaTestRunner.startRunnerWithArgs(JUnit5IdeaTestRunner.java:74)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)

最佳答案

你的 Mockito 代码有点不对劲。您应该只使用 InjectMocks 注释,而不是使用 new 实例化 UserServiceImpl。应该模拟 UserDao 而不是 UserDaoImpl。在调用 UserService.createUser 之前,您应该为 UserDao.createUser 设置一个模拟,以便在调用时不执行任何操作。

关于java - 为什么我的 Spring Boot 服务测试返回 NullPointerException?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51563841/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com