This is my test service
@RunWith(SpringRunner.class)
class UserServiceTest {
@InjectMocks
UserMapper userMapper = mock(UserMapper.class);
@InjectMocks
UserServiceImpl userServiceImpl=mock(UserServiceImpl.class);
@Mock
UserRepository userRepository = mock(UserRepository.class);
@Mock
UserService userService=mock(UserService.class);
@BeforeEach
public void setup(){
MockitoAnnotations.initMocks(this);
userRepository = Mockito.mock(UserRepository.class);
userServiceImpl = new UserServiceImpl(userRepository);
}
@Test
void add() {
AddUserRequest addUserRequest = new AddUserRequest("guest","1234567890","guest98787@guest.com","1234567890");
User user = new User();
user.setUserId(1);
user.setUid("12345678");
user.setName("guest");
user.setMobileNo("1234567890");
user.setEmail("guest98787@guest.com");
user.setPassword("1234567890");
WalletDetail walletDetail=new WalletDetail();
walletDetail.setWalletId(1);
walletDetail.setUid("12345");
walletDetail.setUser(user);
walletDetail.setWalletAmount(10.0);
user.setWallet(walletDetail);
when(userMapper.addRequestUserToEntity(addUserRequest)).thenReturn(user);
when(userRepository.save(user)).thenReturn(user);
when(userServiceImpl.add(addUserRequest)).thenReturn(user);
User result = userServiceImpl.add(addUserRequest);
verify(userServiceImpl,times(1)).add(addUserRequest);
assertEquals(user.getUserId(), result.getUserId());
}
This is my service layer -implemented Mapstuck
@Slf4j
@Service
@Transactional
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Autowired
private UserMapper userMapper;
@Autowired
private WalletService walletService;
private UserServiceImpl userServiceImpl;
public UserServiceImpl(UserRepository userRepository) {
this.userRepository=userRepository;
}
private UserService userService;
public void setUserService(UserService userService) {
this.userService = userService;
}
@Override
public User add(AddUserRequest addUserRequest) {
log.debug("Request received for user registration: " + addUserRequest);
User user = createUser(addUserRequest);
WalletDetail walletDetail = walletService.createDefaultWallet();
walletDetail.setUser(user);
user.setWallet(walletDetail);
log.debug("User saved with data " + user);
return userRepository.save(user);
}
private User createUser(AddUserRequest addUserRequest) {
User user = userMapper.addRequestUserToEntity(addUserRequest);
user.setCreatedBy(user.getUid());
user.setUpdatedBy(user.getUid());
return user;
}
However, when I run the test code, I get the following error message
java.lang.NullPointerException: Cannot invoke "bytro.user.management.transformer.UserMapper.addRequestUserToEntity(bytro.user.management.model.request.AddUserRequest)" because "this.userMapper" is null
at bytro.user.management.service.impl.UserServiceImpl.createUser(UserServiceImpl.java:64)
at bytro.user.management.service.impl.UserServiceImpl.add(UserServiceImpl.java:53)
at bytro.user.management.service.UserServiceTest.add(UserServiceTest.java:124)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
-when calling a method "addRequestUserToEntity" on a null object reference, "this.userMapper". The error occurred at line 64 of the "UserServiceImpl" class, which was called from line 53 of the same class. The call stack also shows that the error originated from a unit test method "add" in the "UserServiceTest" class.
The NPE usually occurs when an object reference is uninitialized or set to null, and the program attempts to access it. In this case, the "userMapper" object was not initialized or set to null in the "UserServiceImpl" class, causing the program to throw the NPE when calling the "addRequestUserToEntity" method on it.n mapper class is null
Your test is wrong for multiple things.
@RunWith(SpringRunner.class)
is useless and only adds to the start time of the test (or even worse you seem to be mixing JUnit4 and Junit5 in a single test class).@BeforeEach
you are also mixing JUnit4 and JUnit5.With that change your test class.
@ExtendWith(MockitoExtension.class)
to do setup and ditch your @BeforeEach
.@ExtendWith(MockitoExtension.class)
class UserServiceTest {
@InjectMocks
private UserServiceImpl userServiceImpl;
@Mock
private UserMapper userMapper;
@Mock
private UserRepository userRepository;
@Mock
private UserService userService;
@Test
void add() {
AddUserRequest addUserRequest = new AddUserRequest("guest","1234567890","guest98787@guest.com","1234567890");
User user = new User();
user.setUserId(1);
user.setUid("12345678");
user.setName("guest");
user.setMobileNo("1234567890");
user.setEmail("guest98787@guest.com");
user.setPassword("1234567890");
WalletDetail walletDetail=new WalletDetail();
walletDetail.setWalletId(1);
walletDetail.setUid("12345");
walletDetail.setUser(user);
walletDetail.setWalletAmount(10.0);
user.setWallet(walletDetail);
when(userMapper.addRequestUserToEntity(addUserRequest)).thenReturn(user);
when(userRepository.save(user)).thenReturn(user);
User result = userServiceImpl.add(addUserRequest);
assertEquals(user.getUserId(), result.getUserId());
}
NOTE: While this might fix this partially it probably will still fail. As your UserServiceImpl
has more dependencies which you need to mock and inject.