My service layer class is like below.
CategoryServiceImpl.java
#Service
public class CategoryServiceImpl implements CategoryService {
#Autowired
private CategoryRepository categoryRepository;
#Autowired
private DozerBeanMapper dozerBeanMapper;
#Override
public CategoryDto createCategory(CategoryDto categoryDto) {
Category category = categoryRepository.save(dozerBeanMapper.map(categoryDto, Category.class));
return dozerBeanMapper.map(category, CategoryDto.class);
}
#Override
public List<CategoryDto> findAllCategories() {
List<Category> all = categoryRepository.findAll();
return all.stream().map(s -> dozerBeanMapper.map(s, CategoryDto.class)).collect(Collectors.toList());
}
}
MY Test Class is like below.
import com.os.eprocurement.core.dto.CategoryDto;
import com.os.eprocurement.core.model.Category;
import com.os.eprocurement.repository.CategoryRepository;
import com.os.eprocurement.service.impl.CategoryServiceImpl;
import org.dozer.DozerBeanMapper;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.MockitoJUnitRunner;
import java.util.Arrays;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.when;
//#SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
#RunWith(MockitoJUnitRunner.class)
public class CategoryServiceTest {
#InjectMocks
private CategoryServiceImpl categoryService;
#Mock
private CategoryRepository categoryRepository;
#Mock
private DozerBeanMapper dozerBeanMapper;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
}
#Test
public void findAllCategories() {
Category category = new Category();
category.setRootCategoryId("345");
category.setCategoryName("Computers");
category.setCategoryDescription("PC");
category.setBusinessUnitId("123");
CategoryDto categoryDto = new CategoryDto();
categoryDto.setRootCategoryId("345");
categoryDto.setCategoryName("Computers");
categoryDto.setCategoryDescription("PC");
categoryDto.setBusinessUnitId("123");
List<Category> categoryList = Arrays.asList(category);
// List<CategoryDto> categoryDtos = new ArrayList<>();
when(categoryRepository.findAll()).thenReturn(categoryList);
when(dozerBeanMapper.map(categoryDto, CategoryDto.class)).thenReturn(categoryDto);
List<CategoryDto> allCategories = categoryService.findAllCategories();
assertEquals(1, allCategories.size());
}
}
It always emit a nullpointer exception when running above Test. But if I use field injection in service layer as below,
CategoryServiceImpl.java
....
#Autowired
public CategoryServiceImpl(CategoryRepository categoryRepository, DozerBeanMapper dozerBeanMapper) {
this.categoryRepository = categoryRepository;
this.dozerBeanMapper = dozerBeanMapper;
}
....
and modify Test as below,
CategoryServiceTest.java
...
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
categoryService = new CategoryServiceImpl(categoryRepository, dozerBeanMapper);
}
...
Test start running fine. But the issue is, since this is a large project and have already used Field Injection in almost everywhere, It is impossible to change it back to Constructor Injection. Are there any way to avoid this NPE while using Field Injection?
I receive NPE from this line,
CategoryServiceTest.java
...
when(categoryRepository.findAll()).thenReturn(categoryList);
...
Related
The goal of this method is to provide functionality to a service layer method that will find all songs within a PostgreSQL database. I have implemented an interface "SongServiceInterface" in the service layer and in the event I utilize this SongService via instantiation in the main method or even by sending Http Requests via "/songs" endpoint, I receive this error:
Caused by: java.lang.NullPointerException: Cannot invoke "com.techm.react.Wasteland.repository.SongRepo.findAll()" because "this.songRepo" is null.
Please note upon startup the application will persist the objects to database, but using endpoints or methods within this repo/service cause null field error.
I can provide the code below:
Model
package com.techm.react.Wasteland.models;
import lombok.*;
import org.hibernate.annotations.OnDelete;
import org.hibernate.annotations.OnDeleteAction;
import javax.persistence.*;
import java.sql.Time;
#Entity
#Table(name = "song")
#NoArgsConstructor
#AllArgsConstructor
#Getter #Setter
#EqualsAndHashCode
#ToString
public class Song {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
#Column(name = "title")
private String title;
#JoinColumn(name = "album")
#ManyToOne
#OnDelete(action = OnDeleteAction.CASCADE)
private Album album;
#Column(name = "artists")
private String artists;
#Column(name = "track")
private int track;
#Column(name = "track_length")
private Time length;
}
DTO
package com.techm.react.Wasteland.dto;
import com.techm.react.Wasteland.models.Album;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.sql.Time;
#Data
#NoArgsConstructor
#AllArgsConstructor
public class SongDTO {
private String title;
private AlbumDTO album;
private String artists;
private int track;
private Time length;
}
Repo
package com.techm.react.Wasteland.repository;
import com.techm.react.Wasteland.models.Song;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import java.util.List;
#Repository
public interface SongRepo extends JpaRepository<Song, Integer> {
public abstract List<Song> findAll();
public abstract List<Song> findByArtist();
public abstract Song findByTrack();
}
Service
package com.techm.react.Wasteland.service;
import com.techm.react.Wasteland.dto.SongDTO;
import com.techm.react.Wasteland.models.Song;
import com.techm.react.Wasteland.repository.SongRepo;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Configurable;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
#Service #Configurable
public class SongService implements SongServiceInterface{
#Autowired
SongRepo songRepo;
#Autowired
private ModelMapper modelMapper;
public List<SongDTO> findAllSongs() {
List<SongDTO> songDTOS = new ArrayList<>();
List<Song> songs = songRepo.findAll();
for(Song s: songs) {
songDTOS.add(modelMapper.map(s, SongDTO.class));
}
return songDTOS;
}
public SongDTO getSongByTitle(String title) throws NoSuchFieldException {
SongDTO song = new SongDTO();
if(title == song.getTitle()){
return song;
}
else throw new NoSuchFieldException("The song by that title does not exist");
}
public SongDTO findByTrack(int track) {
SongDTO song = new SongDTO();
if(song.getTrack() == track) {
return song;
}
return null;
}
}
Main
package com.techm.react.Wasteland;
import com.techm.react.Wasteland.controller.AlbumController;
import com.techm.react.Wasteland.controller.SongController;
import com.techm.react.Wasteland.service.SongService;
import org.modelmapper.ModelMapper;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#SpringBootApplication
#ComponentScan({"com.server", "com.server.config"})
#EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class WastelandApplication {
#Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
return modelMapper;
}
public static void main(String[] args) {
SpringApplication.run(WastelandApplication.class, args);
SongService songService = new SongService();
System.out.println(songService.findAllSongs());
}
}
When you use new to create an object, it's outside of Spring's context. It won't have the autowired dependencies. Also, you won't be able to use autowired beans in your main (nor should you) as it's a static method. If you want to do this in your app startup, autowire the bean and put the logic in a PostConstruct method.
Here is an example:
public class WastelandApplication {
#Autowired
private SongService songService;
#Bean
public ModelMapper modelMapper() {
ModelMapper modelMapper = new ModelMapper();
return modelMapper;
}
public static void main(String[] args) {
SpringApplication.run(WastelandApplication.class, args);
}
#PostConstruct
public void doSomethingIProbablyShouldNotBeDoing() {
System.out.println(songService.findAllSongs());
}
}
I have a CustomerUserDetailsService class, which is part of an implementation of Spring Boot authentication. I have tested my code manually, and it works correctly, allowing me to successfully log in to my app. However, I am unable to work out how to test the CustomerUserDetailsService.
As a unit test, I believe I would need to mock the userRepository member variable, but whatever I try in my test fails, the reason being userRepository is set to null. I've tried adding the #Repository annotation to userRepository but am told that is not allowed because it is an interface. There's also the fact that loadUserByUsername returns an instance of CustomUserDetails, which is just an implementation of an interface, so I have no idea how I'd mock that dependency?
I've also tried doing some kind of integration test but had similar issues, probably due to incorrect annotations on the test itself. In an ideal world, I'd prefer a unit test and would be extremely grateful for any guidance as to how to set it up.
These are the relevant classes...
CustomerUserDetailsService:
package com.phil.urlshortener.security;
import com.phil.urlshortener.model.User;
import com.phil.urlshortener.repositories.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
public class CustomUserDetailsService implements UserDetailsService {
#Autowired private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
if (user == null) {
throw new UsernameNotFoundException("User not found");
}
return new CustomUserDetails(user);
}
}
User:
package com.phil.urlshortener.model;
import lombok.Data;
import javax.persistence.*;
#Data
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#Column(nullable = false, unique = true, length = 50)
private String username;
#Column(nullable = false, length = 64)
private String password;
}
UserRepository:
package com.phil.urlshortener.repositories;
import com.phil.urlshortener.model.User;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.CrudRepository;
public interface UserRepository extends CrudRepository<User, Long> {
#Query("SELECT u FROM User u WHERE u.username = ?1")
User findByUsername(String username);
}
CustomUserDetails:
package com.phil.urlshortener.security;
import com.phil.urlshortener.model.User;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;
import java.util.Collection;
public class CustomUserDetails implements UserDetails {
private final User user;
public CustomUserDetails(User user) {
this.user = user;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return null;
}
#Override
public String getPassword() {
return user.getPassword();
}
#Override
public String getUsername() {
return user.getUsername();
}
#Override
public boolean isAccountNonExpired() {
return true;
}
#Override
public boolean isAccountNonLocked() {
return true;
}
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public boolean isEnabled() {
return true;
}
}
Maybe you forgot to use mockito annotation #RunWith(MockitoJUnitRunner.class).
Here it's the unit test for CustomUserDetailsService :
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.test.util.ReflectionTestUtils;
import static org.junit.Assert.*;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
#RunWith(MockitoJUnitRunner.class)
public class CustomUserDetailsService {
#Mock
private UserRepository userRepository;
private CustomUserDetailsService customUserDetailsService;
#Before
public void setUp() throws Exception {
customUserDetailsService = new CustomUserDetailsService(userRepository);
}
#Test
public void GIVEN_username_THEN_return_user_details() {
//Arrange
final String username = "existingUserName";
final User user = mock(User.class);
when(userRepository.findByUsername(username)).thenReturn(user);
//Act
final UserDetails userDetails = customUserDetailsService.loadUserByUsername(username);
//Assert
assertNotNull(userDetails);
assertEquals(user, ReflectionTestUtils.getField(userDetails, "user"));
}
}
I have written unit tests for my class and they seem to run fine. But the challenge is I can't get full coverage or get the builder.and(...) operation part to execute or be covered.
Any idea what could be going on? Thank you
This is the utility class to create Predicates
import static java.util.Objects.nonNull;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import javax.persistence.criteria.Predicate;
import lombok.experimental.UtilityClass;
import org.springframework.data.jpa.domain.Specification;
#UtilityClass
public class UsersSearchSpecificationFactory {
public static Specification<User> createSpecification(UsersSearchCriteria criteria) {
final List<Specification<User>> specificationList = new ArrayList<>();
if (nonNull(criteria.getAge()))
specificationList.add(ageSpecification(criteria.getAge()));
if (nonNull(criteria.getAccountType()))
specificationList.add(accountTypeSpecification(criteria.getAccountType()));
if (nonNull(criteria.getAge())) {
specificationList.add(idSpecification(criteria.getId()));
}
return (root, query, builder) -> {
return builder.and(
specificationList.stream()
.map(specification -> specification.toPredicate(root, query, builder))
.toArray(Predicate[]::new)
);
};
}
private static Specification<User> ageSpecification(String value) {
return (root, query, builder) -> builder.isMember(value, root.get("age"));
}
private static Specification<User> accountTypeSpecification(String value) {
return (root, query, builder) -> builder.equal(root.get("accountType"), value);
}
private static Specification<User> idSpecification(UUID value) {
return (root, query, builder) -> builder.equal(root.get("id"), value);
}
}
This is the Repository interface:
import java.util.UUID;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.repository.CrudRepository;
interface UserRepository extends CrudRepository<User, UUID>, JpaSpecificationExecutor<User> {
Page<User> findAll(UsersSearchCriteria criteria, Orderable orderable, PageRequest pageable);
}
The Spock Specification logic is in here
import javax.persistence.EntityManager
import javax.persistence.PersistenceContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
#DataJpaTest
#AutoConfigureTestDatabase
class DatabaseSpecification extends InternalSpecification{
#Autowired
private TestEntityManager tem
#PersistenceContext
private EntityManager em
protected <T> T persist(T entity) {
final persisted = tem.persistAndFlush(entity)
tem.detach(persisted)
return persisted
}
}
This is my test:
import static java.util.UUID.randomUUID
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.data.domain.PageRequest
class UserRepositoryTest extends DatabaseSpecification {
def "should_find_user"() {
given:
userRepository = Mock(UserRepository)
and:
final user = Mock(User) as Specification
final criteria = new UserSearchCriteria(
filter: 'userFilter',
id: 'id'
)
final orderable = new orderable()
final pageable = new pageable()
when:
final foundUser = userRepositoryImpl.findAll(criteria, orderable, pageable)
then:
1 * userRepositoryImpl.repository.findAll(_ as Specification, _ as Pageable) >> new PageImpl<>([user])
and:
foundUser.content.get(0) == user
}
}
Thank you #LeonardBrünings for the guidance.
So, the mistakes I was making were two:
I was mocking the repository the wrong way instead of using #DataJpaTest and then injecting the repository.
I was creating my generic class wrong
The code below worked with 100% coverage, of course, bits have been omitted
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
import javax.persistence.EntityManager
import javax.persistence.PersistenceContext
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager
import org.springframework.data.jpa.domain.Specification
import org.springframework.core.env.Environment
import spock.lang.Specification
#DatabaseTests
#DataJpaTest
class UserRepositoryTest extends Specification {
#Autowired
private TestEntityManager testEntityManager
#Autowired
private UserRepository userRepository
def "should_find paged_users_using_search_criteria"() {
given:
final id = randomUUID()
and:
final orderable = new Orderable()
final pageable = new PageableFor()
final user = new UserId('an user')
final organization = persistAndDetach(new Organization(id: id, name: 'organization'))
final user = persistAndDetach(new User(
....
// omitted
....
))
final criteria = new SearchCriteria(
....
// omitted
....
)
when:
final foundPage = userRepository.findAll(criteria, orderable, pageable)
then:
foundPage.content[0]== user
}
}
protected <T> T persistAndDetach(T entity) {
final persisted = testEntityManager.persistAndFlush(entity)
testEntityManager.detach(persisted)
return persisted
}
I have abstract user service where I autowired two beans: Repository and AbstractMapper, but when I run test for that class, all faild with NullPointerException. When I run, for example, save test for that service in dubug, it show me that both beans are null. Anybody had this problem? This is my code:
AbstractService
package com.example.shop.service;
import com.example.shop.dto.AbstractMapper;
import com.example.shop.entity.Identifable;
import com.example.shop.repository.IRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
import java.util.stream.Collectors;
#Service`enter code here`
public abstract class AbstractService<E extends Identifable, D> implements IService<E, D> {
private IRepository<E> repository;
private AbstractMapper<E, D> abstractMapper;
#Autowired
public AbstractService(IRepository<E> repository, AbstractMapper<E, D> abstractMapper) {
this.repository = repository;
this.abstractMapper = abstractMapper;
}
#Override
public D get(Long id) {
E e = repository.get(id);
return abstractMapper.entityToDto(e);
}
#Override
public List<D> getAll() {
List<E> all = repository.getAll();
List<D> allDtos = all.stream()
.map(e -> abstractMapper.entityToDto(e))
.collect(Collectors.toList());
return allDtos;
}
#Override
public E save(D d) {
E e = abstractMapper.dtoToEntity(d);
return repository.save(e);
}
#Override
public E update(D d) {
E e = abstractMapper.dtoToEntity(d);
return repository.update(e);
}
#Override
public E delete(D d) {
E e = abstractMapper.dtoToEntity(d);
return repository.delete(e);
}
#Override
public void deleteAll() {
repository.deleteAll();
}
}
UserServiceImpl
package com.example.shop.service;
import com.example.shop.dto.UserDto;
import com.example.shop.dto.UserMapper;
import com.example.shop.entity.User;
import com.example.shop.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
#Service
public class UserServiceImpl extends AbstractService<User, UserDto> implements UserService {
private UserRepository repository;
private UserMapper userMapper;
#Autowired
public UserServiceImpl(UserRepository repository, UserMapper userMapper) {
super(repository, userMapper);
}
}
Abstract Mapper
package com.example.shop.dto;
import org.springframework.stereotype.Component;
#Component
public interface AbstractMapper<E, D> {
E dtoToEntity(D d);
D entityToDto(E e);
}
User Mapper:
package com.example.shop.dto;
import com.example.shop.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
#Component
public class UserMapper implements AbstractMapper<User, UserDto> {
private AccountMapper accountMapper;
#Autowired
public UserMapper(AccountMapper accountMapper) {
this.accountMapper = accountMapper;
}
#Override
public User dtoToEntity(UserDto dto) {
if (dto == null) {
return null;
}
User user = new User();
user.setId(dto.getId());
user.setEmail(dto.getEmail());
user.setPassword(dto.getPassword());
user.setLogin(dto.getLogin());
user.setAccount(accountMapper.dtoToEntity(dto.getAccountDto()));
return user;
}
#Override
public UserDto entityToDto(User user) {
if (user == null) {
return null;
}
UserDto dto = new UserDto();
dto.setEmail(user.getEmail());
dto.setLogin(user.getLogin());
dto.setPassword(user.getPassword());
dto.setId(user.getId());
dto.setAccountDto(accountMapper.entityToDto(user.getAccount()));
return dto;
}
}
Class with #SpringBootApplication
package com.example.shop;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class ShopApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(ShopApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
System.out.println("Test");
}
}
And my tests for Service:
package com.example.shop.service;
import com.example.shop.dto.UserDto;
import com.example.shop.entity.User;
import com.example.shop.repository.IRepository;
import org.junit.After;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import static org.mockito.Mockito.*;
#RunWith(SpringRunner.class)
#SpringBootTest
public class UserServiceImplTest {
private static final Long VALID_ID = 1L;
#Mock
private IRepository<User> repository;
#InjectMocks
private UserServiceImpl service;
#After
public void tearDown() {
repository.deleteAll();
}
#Test
public void get() {
service.get(VALID_ID);
verify(repository, times(1)).get(anyLong());
}
#Test
public void save() {
UserDto dto = createUser();
service.save(dto);
verify(repository, times(1)).save(any());
}
#Test
public void getAll() {
service.getAll();
verify(repository, times(1)).getAll();
}
#Test
public void update() {
UserDto dto = createUser();
service.update(dto);
verify(repository, times(1)).update(any());
}
#Test
public void delete() {
UserDto dto = createUser();
service.delete(dto);
verify(repository, times(1)).delete(any());
}
#Test
public void deleteAll() {
service.deleteAll();
verify(repository, times(1)).deleteAll();
}
private UserDto createUser() {
return new UserDto();
}
}
There are several problems with this code. First of all you do not need to annotate the abstract classes with service or component. Abstract classes cannot be instantiated, therefore there is no bean.
Second: autowire of classes having generics wont work. As soon as you have several bean, it wont be unique anymore.
Checkout if your classes get instantiated. Maybe you need to add #componentscan.
Your test is located under: com.example.shop.service and therefore it only scans the beans under this package. You should either move your test or add the beans by using the componentscan annotation
I am learning to write a UnitTest for my JSF project which has ManangedBeans and Session Beans
I have a problem invoking the EJB from Mockito test
package Test;
import ejb.CountrySession;
import java.io.Serializable;
import javax.ejb.EJB;
import javax.inject.Named;
import javax.faces.view.ViewScoped;
#Named(value = "countryMB")
#ViewScoped
public class CountryMB implements Serializable {
#EJB
private CountrySession countSession;
//
private String countryName;
//
private StatusMsg msg;
public CountryMB() {
}
public void setMsg(StatusMsg msg) {
this.msg = msg;
}
public void setCountSession(CountrySession countSession) {
this.countSession = countSession;
}
public String getCountryName() {
return countryName;
}
public void setCountryName(String countryName) {
this.countryName = countryName;
}
public void ajaxAll() {
}
public void saveCountry() {
if (countryName != null && !countryName.trim().isEmpty()) {
boolean chk = countSession.chkCountry(countryName);
if (!chk) {
chk = countSession.addCountry(countryName);
if (chk) {
msg.addInfo("Add Country", "New Country added");
} else {
msg.addError("Add Country", "Unable to add Country");
}
} else {
msg.addWarn("Add Country", "Country already exists");
}
} else {
msg.addWarn("Add Country", "Required parameter not available");
}
}
}
Now in my Test Code i have the following
package Test;
import ejb.CountrySession;
import entities.Country;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
public class CountryMBTest {
#Mock
private CountryMB countryMB;
#Mock
private StatusMsg sm;
#Mock
private CountrySession countSession;
#Mock
private EntityManager em;
#Mock
private Query qry;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
countryMB = new CountryMB();
countryMB.setMsg(sm);
countryMB.setCountSession(countSession);
}
#After
public void after() {
countryMB = null;
}
#Test
public void infoCountrySave() {
countryMB.setCountryName("Test");
countryMB.saveCountry();
verify(sm).addInfo("Add Country", "New Country added");
}
#Test
public void errorCountrySave() {
countryMB.setCountryName("Test");
countryMB.saveCountry();
verify(sm).addError("Add Country", "Unable to add Country");
}
#Test
public void warnCountrySave() {
countryMB.setCountryName("Test");
countryMB.saveCountry();
verify(sm).addWarn("Add Country", "Country already exists");
}
#Test
public void chkCountSave() {
List<Country> countLst = null;
Country dum = mock(Country.class);
EntityManager em = mock(EntityManager.class);
Mockito.when(em.find(Country.class, 111)).thenReturn(dum);
CountrySession cs = Mockito.mock(CountrySession.class);
Mockito.when(cs.chkCountry("Test")).thenCallRealMethod();
Mockito.when(cs.getEm()).thenReturn(em);
String name = "Test";
Assert.assertNull(cs.chkCountry(name));
}
}
My table has only one Record pk=1, Country=Test
The above test code never check the session beans, it just throw
java.lang.NullPointerException
at ejb.CountrySession.chkCountry(CountrySession.java:67)
at Test.CountryMBTest.chkCountSave(CountryMBTest.java:112)
And for infoCountrySave() & warnCountrySave() it just never check the supplied value in the database.
As i have never used any UnitTest earlier so i really don't know if what i am doing is correct, moreover i could not figure out any working code by googling.
It will be of great help if anyone can guide me to some resource available online or even let me know what is that i need to correct to get the above mockito test work with the ejb part.
Change #Mock with #InjectMocks for
private CountryMB countryMB
and when you get java.lang.NullPointerException. Mostly you miss inject some class or some dependency on by called when