Why is my Spring Boot Service test returning a NullPointerException?
Why is my Spring Boot Service test returning a NullPointerException?
Lately I have been trying to test my Spring Boo(2.0.3) Service, but I have been receiving a NullPointerException. The userDAOImpl implements the userDAO interface,
Here is the serviceImpl class, it implements the interface Service:
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();
}
}
Here's my 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;
}
}
}
Here is my JUnit 5 Spring Boot test:
package app.clothapp.ServiceImpl;
import app.clothapp.DAO.UserDAO;
import app.clothapp.DaoImpl.UserDAOImpl;
import app.clothapp.Model.User;
import app.clothapp.Service.UserService;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
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.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import static org.junit.jupiter.api.Assertions.assertEquals;
@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 = new UserServiceImpl();
@Mock
private UserDAOImpl userDAO = new UserDAOImpl();
@BeforeEach
void setUp() {
MockitoAnnotations.initMocks(this.getClass());
}
@Test
void createUser() {
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() {
}
}
As you can see, I create an user utilizing the UserFactory, mock the jdbcTemplate and userDAOImpl, then inject them into the UserServiceImpl(). THen within the createUser() test, I create the user with the service, and set up the Mockito.when, and test if the user is there within the database.
However, I receive a NullPointerException, though I am not sure why. Could anyone provide me with a hint?
DEBUG] 2018-07-27 14:37:43.736 [main] UserServiceImplLogger - Creating an user app.clothapp.ServiceImpl.UserServiceImpl
java.lang.NullPointerException
at app.clothapp.ServiceImpl.UserServiceImpl.createUser(UserServiceImpl.java:29)
at app.clothapp.ServiceImpl.UserServiceTest.createUser(UserServiceTest.java:53)
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)
Process finished with exit code 255
1 Answer
1
Your Mockito code is a little off. Instead of instantiating UserServiceImpl
with new
, you should just have the InjectMocks
annotation. UserDao
should be mocked instead of UserDaoImpl
. Before you call UserService.createUser
, you should set a mocked for UserDao.createUser
to do nothing when called.
UserServiceImpl
new
InjectMocks
UserDao
UserDaoImpl
UserService.createUser
UserDao.createUser
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.