Mocked object not getting in service Here is my below code
#RunWith(SpringJUnit4ClassRunner.class)
#SpringApplicationConfiguration(classesExternalProviderMain.class)
#ActiveProfiles(ApplicationConstants.DEVELOPMENT_PROFILE)
#WebAppConfiguration
public class EmployeeServiceTest {
#InjectMocks
EmployeeService employeeService;
#Mock
EmployeeRepository employeeRepository;
String name;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testEmployee() {
Mockito.when(employeeRepository.findByName(name)).thenReturn(getEmployee());
List<Employee> resultedEmployees = employeeService.getEmployeeByName("mike");
}
private List<Employee> getEmployee(){
//here is the logic to return List<Employees>
}
}
public EmployeeServiceImpl implements EmployeeService{
#Autowired
EmployeeRepository employeeRepository;
employeeService.
public List<Employee> getEmployeeByName(String name){
List<Employee> employees = employeeRepository.findByName(name);
//Here I does't want to hit the real database so I have mocked it in testcase but I am getting empty list when I debug it. So can you please tell me what i did wrong in my "EmployeeServiceTest" to get List<Employee>
}
}
So is there any additional logic required in testcase to get the mocked object.
The problem is you are not mocking the call
employeeRepository.findByName("mike")
but you are mocking
employeeRepository.findByName(null)
since your variable name was never initialized. Change your code to:
Mockito.when(employeeRepository.findByName("mike")).thenReturn(getEmployee());
Related
I am creating test cases, in one of my service class method I am using mapStruct to map entity into dto class.
This is my mapper class
#Mapper(componentModel = "spring")
public interface UserMapper {
List<UserDto> toUserDto(List<UserEntity> users);
}
below is how I am injecting in my service class
#Service
#RequiredArgsConstructor
public class UserServiceImpl implements UserService{
private final UserMapper userMapper;
This is how I am using it
List<UserDto> userDto = userMapper.toUserDto(lst);
this is how I am doing it in my Test class
#RunWith(MockitoJUnitRunner.class)
#SpringBootTest(classes = Application.class)
public class ApplicationTest {
#Mock
private UserRepository userRepo;
#Mock
private UserMapper userMapper;
#InjectMocks
private UserServiceImpl userServiceImpl;
#Test
public void contextLoads() {
then(controller).isNotNull();
then(userServiceImpl).isNotNull();
}
#Test
public void getAllUser() {
List<UserEntity> lst = new ArrayList<UserEntity>();
UserEntity userOne = new UserEntity();
userOne.setEmpFullname("Test Test1");
userOne.setUserId("marina");
userOne.setFlag("Y");
UserEntity usertwo = new UserEntity();
usertwo.setEmpFullname("Test Test2");
usertwo.setUserId("test");
usertwo.setFlag("Y");
lst.add(userOne);
lst.add(usertwo);
when(userRepo.findByStatus("W")).thenReturn(lst);
try {
List<UserDto> pendingUsersList = userServiceImpl.getPendingUser();
assertEquals(2, pendingUsersList.size());
} catch (GeneralException e) {
e.printStackTrace();
}
}
}
when I am running my test cases I am able to see these 2 records in entity class but when this line executes
List<UserDto> userDto = userMapper.toUserDto(lst); it gives me blank array.
Note - In my entity Class I have many fields but from test class I am passing only 3 parameters.
You have annotated your UserMapper with a #Mock annotation, without writing the mockito configuration for this mock. Then the blank array is expected.
Remove the #Mock annotation, or specify what should be returned by the mock.
For example :
#RunWith(MockitoJUnitRunner.class)
#SpringBootTest(classes = Application.class)
public class ApplicationTest {
#Mock
private UserRepository userRepo;
#Spy
private UserMapper userMapper = Mappers.getMapper(UserMapper.class);
#InjectMocks
private UserServiceImpl userServiceImpl;
In tests i mock DateService to have the same date every time when i run the test, but when i use DateServie in other service then the mock retun null all the time. It is strange because the mock works in my custom date time provder. Here is the code:
Its work here:
#Service(MyDateTimeProvider.MY_DATE_TIME_PROVIDER)
public class MyDateTimeProvider implements DateTimeProvider {
public static final String MY_DATE_TIME_PROVIDER = "MyDateTimeProvider";
#Autowired
private DateService dateService;
#Override
public Optional<TemporalAccessor> getNow() {
return Optional.of(dateService.getCurrentDate().toInstant());
}
}
#Service
public class DateService {
public Date getCurrentDate() {
return new Date();
}
}
Its not work in the UserService:
#SpringBootTest
public class Test{
#MockBean
protected DateService dateService;
#BeforeEach
public void beforeEach() { Mockito.when(dateService.getCurrentDate()).thenReturn(DEFAULT_DATE_TIME.toDate());
}
...
}
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
#Autowired
private DateService dateService;
private User createNewUser(final UserDto dto) {
User user = new User();
user.setEmail(dto.getEmail());
user.setRegistrationDate(dateService.getCurrentDate()); // i got null here
return userRepository.save(user);
}
}
What did i wrong? Thank you!
My colleague helped me. My problem was: i used "UserService" in a method with #PostConstuct annotation, so its run before the mock happened.
I am running Junit Test cases which is throwning NullPointerException Here is my Junit Test Class Structure
#RunWith(SpringJUnit4ClassRunner.class)
public class EmployeeTest {
#InjectMocks
EmployeeRepository empRepo;
#InjectMocks
EmployeeService empService;
#Mock
EntityManager entityManager;
List<Employee> empList=new ArrayList<Employee>();
#Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
#Test
public void getEmployyeList(){
Employee e = new Employee(111,'Raunak','kumar','Hero Inc');
List<Employee> empList=empService.getAllEmployee();
Employee e1 = empList.stream().filter(emp->emp.getEmpId()==111).findAny().get();
assertEquals(e,e1);
}
}
And On the EmployeeService i am using EntityManager looks like
public class EmployeeService{
#Autowired
EntityManager em;
public List<Employee> getAllEmployee(){
return em.createNativeQuery("select e.* from employee e").getResultList();
}
}
When i am debugging the code found that em.createNativeQuery("select e.* from employee e") returns null. From the Rest API its working fine.
tried with
when(empRepo.findAll()).thenReturn(empList);
assertThat(users, containsInAnyOrder(
hasProperty("lastName", is("Kumar"))
));
But empRepo.findAll() also return []
you have to stub mock entity manager using mockito's when and thenReturn in your test case (getEmployyeList) like below , this should resolve NPE
#Test
public void getEmployyeList(){
Employee e = new Employee(111,'Raunak','kumar','Hero Inc');
Query query = mock(Query.class);
when(entityManager.createNativeQuery(anyString())).thenReturn(query);
doReturn(Arrays.asList(e)).when(query).getResultList();
List<Employee> empList=empService.getAllEmployee();
Employee e1 = empList.stream().filter(emp->emp.getEmpId()==111).findAny().get();
assertEquals(e,e1);
}
So I have this class (used lombok):
#RequiredArgsConstructor
#Service
public class ServiceImpl {
private final BookService bookService;
#Autowired
private TableService tableService;
public void method() {
if (!bookService.isEmpty()) return;
Object table = tableService.getObject();
}
}
My test class:
#ExtendWith(MockitoExtension.class)
#RunWith(JUnitPlatform.class)
public class ServiceImplTest {
#Mock BookService bookService;
#Mock TableService tableService;
#InjectMocks ServiceImpl serviceImpl;
#Test
public void testMethod() {
when(bookService.isEmpty()).thenReturn(true);
when(tableService.isEmpty()).thenReturn(new Object());
serviceImpl.method();
}
}
If I run it, the bookService is null. It is not injected in the class. When the code is at the if (!bookService.isEmpty()) return; the bookService is null.
if I change my testMethod to this:
#Test
public void testMethod() {
MockitoAnnotations.initMocks(this);
when(bookService.isEmpty()).thenReturn(true);
when(tableService.isEmpty()).thenReturn(new Object());
serviceImpl.method();
}
So I added MockitoAnnotations.initMocks(this); then the code Object table = tableService.getObject(); in my class returns null. So the tableService is not null, but the getObject() return null;
Any idea how to fix it? I am not let to change the class code.
Thanks in advance.
I want to InjectMocks into my interface and not my service class , so far its not possible with Mockito (I am using Mockito 2.8.9). I have used SpringBoot and using #MockBean I am able to test interfaces of services but with #Mock of SpringMvc I can only test a concrete class, why and what can I do to test services?
Any suggestion on how to get this to interface level.
#RunWith(MockitoJUnitRunner.class)
#ContextConfiguration(classes = EmployeeServiceImpl.class)
public class EmployeeServiceTest {
#org.mockito.Mock
private EmployeeDao employeeDao;
#InjectMocks
private EmployeeServiceImpl employeeService ;
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
}
#Test
public void SaveEmployee() throws Exception {
Employee employee = new Employee();
employee.setEmployeeName("valentine");
employee.setSalary(400);
employee.setDepartmentId(1);
employee.setEmployeeId(1);
Employee employee1 ;
when(employeeDao.addEmployee(employee)).thenReturn(employee);
employee1 = employeeService.saveEmployee(employee);
org.junit.Assert.assertNotNull(employee);
assertEquals(employee1.getSalary(), employee.getSalary());
Mockito.verify(employeeDao).addEmployee(employee);
}
So i solved this by first creating Bean in Config class that returns interface of Dao
#Profile("test")
#Configuration
public class Config {
#Bean
#Primary
public EmployeeDao employeeDao(){
return Mockito.mock(EmployeeDao.class);
}
}
Then i used the profile in my test and set configContxt TO my Config Class
#ActiveProfiles("test")
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes ={ EmployeeServiceImpl.class, Config.class})
public class EmployeeServiceTest1 {
#Autowired
private EmployeeDao employeeDao;
#Autowired
private EmployeeService employeeService;