Mockito - Testing method that calls private methods - mockito

I was trying to find solution but haven't found yet. I tried to test public method which has calls of the couple of private ones inside. One of the problem that private method retrieves Hibernate's Criteria by generic method that in its turn retrieves it through chain of another generic methods. Please take a look at the code below. Frankly I'm not sure that it is possible to test that case but if anyone has ideas please suggest them:
ConcreteDao
public class ConcreteDao extends EntityDao<ConcreteEntity> {
public Class<ConcreteEntity> getClassType() {
return ConcreteEntity.class;
}
}
EntityDao
public abstract class EntityDao<T> extends AbstractDao<T>{
public List<T> getEntityByFilter(EntityFilter filter) {
Criteria criteria = getCriteriaByFilter(filter.getFilters());
criteria.setMaxResult(filter.getMaxResult());
criteria.setFirstResult(filter.getFirstResult());
criteria.addOrder(Order.asc(filter.getSortedField()));
criteria.list();
}
private Criteria getCriteriaByFilter(List<CustFilter> filters) {
Criteria criteria = getCriteria();
for (CustFilter filter : filters) {
filter.addrestrictionToCriteria(criteria, filter.getProperty(), filter.getValue());
}
return criteria;
}
}
AbstractDao
public abstract class AbstractDao<T> {
private EntityManagerFactory entityManagerFactory;
public abstract getClassType();
public Criteria getCriteria() {
return getSession().createCriteria(getClassType());
}
public Session getSession() {
Session session = (Session) getEntityManager().getDelegate();
return session;
}
public EntityManager getEntityManager() {
entityManagerFactory.getEntityManager();
}
}
Test class
#RunWith(MockitoJUnitRunner.class)
public class ConcreteDaoTest {
#Mock
private EntityManager entityManager;
#Mock
private Session session;
#Mock
private Criteria criteria;
private List<CustFilter> filters;
private EntityFilter entityFilter;
private List<ConcreteEntity> resultList;
#InjectMocks
private ConcreteDao concreteDao = new ConcreteDao;
public void init() {
filters = new ArrayLis<CustFilter>();
CustFilter custFilter = new CustFilter();
//fill filter;
filters.add(custFilter);
entityFilter = new EntityFilter();
//fill entityFilter
entityFilter.setFilters(filters);
ConcreteEntity concreteEntity = new ConcreteEntity();
resultList = new ArrayList<ConcreteEntity>();
resultList.add(concreteEntity);
}
#Test
public void getEntityByFilterTest() {
when(concreteDao.getEntityManager).thenReturn(entityManager);
when(concreteDao.getSession()).thenReturn(session);
when(concretedao.getCriteria()).thenReturn(criteria);
when(filter.getFilters()).thenReturn(filters);
when(filter.getMaxResult()).thenReturn(10);
when(filter.getFirstResult()).thenReturn(0);
when(filter.getSortedField()).thenReturn("firstName");
when(criteria.list()).thenReturn(resultList);
List<ConcreteEntity> result = concreteDao.getEntityByFilter(entityFilter);
Assert.assertThen(result. is(notNullValue()));
}
}

With Mockito, you cannot mock private method calls.
Try PowerMockito with which you can mock any kinds of methods like static methods, private methods, local method instantiations and so on.

Related

Convert List of Objects to List of Strings

I'm using Spring data jpa findAll() method. So it returns List of objects.
here is the entity.
#Entity
#Table(name = "country")
#Data
public class CountryEntity {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "country_id")
private Long id;
#Column(name = "country_name")
private String name;
#OneToMany(mappedBy ="countryEntity")
private Collection<GovernmentEntity> governments;
}
and data jpa findAll() method is
List<CountryEntity> entities = countryRepo.findAll();
I want to get list of Country names as String WITHOUT USING loops or streams (performance issues).
I used streams and it works fine with javaFx ListView
#FxmlView("/address.fxml")
#Component
#RequiredArgsConstructor
public class HomeController implements Initializable {
private ObservableList<String> countriesNames;
#FXML
private ListView<String> countryListView;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
List<CountryEntity> entities = countryRepo.findAll();
List <String> countryList = entities.stream().map(o-> Objects.toString(o.getName())).collect(Collectors.toList());
countriesNames = FXCollections.observableList(countryList);
countryListView.getItems().addAll(countriesNames);
}
}
Make your ListView a ListView<CountryEntity>, and use a cell factory to customize the display:
public class HomeController implements Initializable {
private ObservableList<String> countriesNames;
#FXML
private ListView<CountryEntity> countryListView;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
List<CountryEntity> entities = countryRepo.findAll();
countryListView.getItems().addAll(entities);
countryListView.setCellFactory(lv -> new ListCell<CountryEntity>() {
#Override
protected void updateItem(CountryEntity country, boolean empty) {
super.updateItem(country, empty);
if (empty || country == null) {
setText("");
} else {
setText(country.getName()); // or however you want to display it
}
});
}
}
If you genuinely only want a list of country names, and don't want to retrieve a list of CountryEntitys and extract the names from them, then you need to define a method in your repository for the purpose:
public interface CountryEntityRepository extends JpaRepository<CountryEntity, Long> {
// existing methods...
#Query("select c.name from CountryEntity c")
List<String> findCountryNames() ;
}
And then of course just do
#FXML
private ListView<String> countryListView ;
#Override
public void initialize(URL url, ResourceBundle resourceBundle) {
countryListView.getItems().addAll(countryRepo.findCountryNames());
}
However, the first approach is almost certainly preferred. You will likely need the other data in the CountryEntity at some point.

Springboot mockito mock a field

I want to mock the TreeMap in Service class, I tried to mock using TreeMap<String, String> requestsMap = Mockito.mock(TreeMap.class); But the map is getting null at runtime.
#RunWith(SpringRunner.class)
#SpringBootTest
#WebAppConfiguration
public class ServiceTest {
#InjectMocks
private Service service;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
TreeMap<String, String> requestsMap = Mockito.mock(TreeMap.class);
}
}
#Service
public class Service {
private TreeMap<String, String> requestsMap = null;
}
Your Service class doesn't actually do anything but declare and initialize the requestMap to null. Also, your test method doesn't do anything other than declare a mock requestMap.
In addition to the code you have, write a method in the Service that uses the request map and just declare/autowire the requestMap. In your test, use the #Mock annotation on a declaration of your mock requestMap. Finally, use the mocked requestMap in your test.
For example:
#RunWith(SpringRunner.class)
#SpringBootTest
#WebAppConfiguration
public class ServiceTest {
#Mock
TreeMap<String, String> requestsMap;
#InjectMocks
private Service service;
#Before
public void init() {
MockitoAnnotations.initMocks(this);
}
#Test
public void test() {
when(requestMap.get("foo")).thenReturn("bar");
String result = service.doSomething();
assertEquals(result, "bar");
}
}
#Service
public class Service {
#Autowired
private TreeMap<String, String> requestsMap;
public String doSomething() {
return requestMap.get("foo");
}
}

Why is my Primefaces.current() returning null

So, I have this page:
#Named("ManagementPage")
#ViewScoped
#Getter
#Setter
#Join(path = "/{appScope}/admin/management",
to = "/pages/scoped/managementOverview.xhtml")
#Page(
group = "kitchen",
icon = "mdi mdi-comment-text",
key = "management",
navigation = Page.Navigation.ADMIN_SCOPED,
outcome = "/pages/scoped/managementOverview.xhtml",
auth = #PageAuth(value = "MANAGER_ACCESS", scoped = true))
public class ManagementPage implements Serializable {
private static final long serialVersionUID = 1L;
#Inject
private ManagementModel model;
#PostConstruct
public void init() {
this.model.init();
}
}
It's ViewScoped. And the model for it is:
#Log4j
#Dependent
#Getter
#Setter
public class ManagementModel implements Serializable {
...
}
I want, whenever I receive an event, to refresh some UI on the frontend (I'm using JSF). For that, I've created this dispatcher:
#ApplicationScoped
public class OrderEventDispatcher {
private static final List<ManagementModel> subscriptions = new ArrayList<>();
public static void addSubscriber(ManagementModel subscriber) {
subscriptions.add(subscriber);
}
public static void removeSubscriber(ManagementModel subscriber) {
subscriptions.remove(subscriber);
}
public void observerOrderCreated(#Observes FrontendEvent frontendEvent) {
if(frontendEvent instanceof ContentItemCreatedEvent){
if(!"order".equals(((ContentItemCreatedEvent) frontendEvent).getTypeKey())){
return;
}
}
if(frontendEvent instanceof ContentItemChangedEvent){
if(!"order".equals(((ContentItemChangedEvent) frontendEvent).getTypeKey())){
return;
}
}
subscriptions.forEach(ManagementModel::orderInit);
}
}
(I have implemented a proper equals for this in my model)
For my dispatcher to work, I'm subcribing with my model to it (the methods are inside the model)
#PostConstruct
public void init() {
id = totalIds++;
OrderEventDispatcher.addSubscriber(this);
...
And then i unsubscribe before I destroy the model:
#PreDestroy
public void preDestroy() {
OrderEventDispatcher.removeSubscriber(this);
}
And finally, the methods I call from my dispatcher:
public void orderInit() {
loadMergedOrders();
initializeDonut();
PrimeFaces.current().executeScript("orderInit()");
}
I'm doing all this in order to refresh my page (even when multiple instance of the same page are open) in reaction to an event (some item is created/deleted/modified, of that the FrontendEvent takes care). Now the issue is that my PrimeFaces.current() is always returning null, I've added a breakpoint in the init() method and I tried using PrimeFaces.current() and it worked then, but then when I went through the Dispatcher and into the orderInit() with the debugger I've seen that PrimeFaces.current() now returns null. Does anyone have any idea what I'm doing wrong? If not how to fix this then maybe a different approach to solving this. Thanks for your time!

#CacheEvict with key="#id" throws NullPointerException

I'm trying to use Spring Caching annotations #Cacheable and #CacheEvict together with the GuavaCacheManager.
I've created a test case with these two tests:
cachesById - verifies that two invocations to a method annotatted with #Cacheable returns the same object
evict - verifies that two different instances are returned if a method annotated with #CacheEvict is called in-between those two invocations
Both work fine when i don't specify a key for #CacheEvict, however when I do i get the following exception:
java.lang.NullPointerException
at com.google.common.base.Preconditions.checkNotNull(Preconditions.java:210)
at com.google.common.cache.LocalCache$LocalManualCache.invalidate(LocalCache.java:4764)
at org.springframework.cache.guava.GuavaCache.evict(GuavaCache.java:135)
at org.springframework.cache.interceptor.AbstractCacheInvoker.doEvict(AbstractCacheInvoker.java:95)
at org.springframework.cache.interceptor.CacheAspectSupport.performCacheEvict(CacheAspectSupport.java:409)
at org.springframework.cache.interceptor.CacheAspectSupport.processCacheEvicts(CacheAspectSupport.java:392)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:362)
at org.springframework.cache.interceptor.CacheAspectSupport.execute(CacheAspectSupport.java:299)
at org.springframework.cache.interceptor.CacheInterceptor.invoke(CacheInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:653)
at com.myorg.caching.CacheTest$Repo$$EnhancerBySpringCGLIB$$eed50f3e.update(<generated>)
at com.myorg.caching.CacheTest.evict(CacheTest.java:50)
This can be reproduced by executing the below test.
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(
classes = { Repo.class, CacheTest.SpringConfig.class },
loader = AnnotationConfigContextLoader.class)
public class CacheTest {
private static final String CACHE_NAME = "cacheName";
#Inject
private Repo repo;
#Test
public void cachesById() {
Entity aResult1 = repo.getEntity(1);
Entity aResult2 = repo.getEntity(1);
assertEquals(aResult1.getId(), aResult2.getId());
assertSame(aResult1, aResult2);
}
#Test
public void evict() {
Entity aResult1 = repo.getEntity(1);
repo.update(aResult1);
Entity aResult2 = repo.getEntity(1);
assertEquals(aResult1.getId(), aResult2.getId());
assertNotSame(aResult1, aResult2);
}
/** Mock repository/entity classes below. */
#Component
public static class Repo {
#Cacheable(value = CACHE_NAME, key = "#id")
public Entity getEntity(int id) {
return new Entity(id);
}
#CacheEvict(value = CACHE_NAME, key = "#id")
public void update(Entity e) {
}
}
public static class Entity {
private int id;
public Entity(int id) {
super();
this.id = id;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
}
/** Guava Cachemanager Spring configuration */
#Configuration
#EnableCaching
public static class SpringConfig {
#Bean
public CacheManager cacheManager() {
GuavaCacheManager manager = new GuavaCacheManager(CACHE_NAME);
manager.setCacheBuilder(CacheBuilder.newBuilder().expireAfterWrite(
1, TimeUnit.MINUTES).recordStats());
return manager;
}
}
}
However the test passes if I change
#CacheEvict(value = CACHE_NAME, key = "#id")
public void update(Entity e) {
into:
#CacheEvict(value = CACHE_NAME)
public void update(Entity e) {
..but then I'm missing the point where I need to specify the cache key for Entity. Does anyone know what I'm missing?
Thanks!
You have to fix you component class from
#Component
public static class Repo {
#Cacheable(value = CACHE_NAME, key = "#id")
public Entity getEntity(int id) {
return new Entity(id);
}
#CacheEvict(value = CACHE_NAME, key = "#id")
public void update(Entity e) {
}
}
to
#Component
public static class Repo {
#Cacheable(value = CACHE_NAME, key = "#id")
public Entity getEntity(int id) {
return new Entity(id);
}
#CacheEvict(value = CACHE_NAME, key = "#e?.id")
public void update(Entity e) {
}
}
Why? In getEntity method you're caching an Entity object using int id, you have to pass the same int id into the #CacheEvict annotated method. You don't have to change method's signature - by using SPEL you can "get into" entity and use its id field.
Hope I helped.

Enum-Like object which contains properties

I am trying to figure out a way to have a class full of static objects which each can have a variety of static properties.
I want to be able to pass these properties around and even set them as static properties of other object and I also want to be able to switch through the objects.
Here is an example illustrating what I mean:
Creating and Sending a Message
class Program
{
static void Main(string[] args)
{
MarketOrder Order = new MarketOrder("DELL", MessageProperties.SecurityType.Equity, MessageProperties.ExchangeDestination.ARCA.PostOnly);
SendOrder(Order);
Console.ReadLine();
}
public static void SendOrder(MarketOrder Order)
{
switch (Order.SecurityType)
{
case MessageProperties.SecurityType.Equity:
// Equity sending logic here
break;
case MessageProperties.SecurityType.Option:
// Option sending logic here
break;
case MessageProperties.SecurityType.Future:
// Future sending logic here
break;
}
}
}
This does not want to compile because it won't let me switch the Order.SecurityType object.
MarketOrder Class
public class MarketOrder
{
public readonly string Symbol;
public readonly MessageProperties.SecurityType SecurityType;
public readonly MessageProperties.ExchangeDestination ExchangeDestination;
public MarketOrder(string Symbol, MessageProperties.SecurityType SecurityType, MessageProperties.ExchangeDestination ExchangeDestination)
{
this.Symbol = Symbol;
this.SecurityType = SecurityType;
this.ExchangeDestination = ExchangeDestination;
}
}
MessageProperties Class
public abstract class MessageProperties
{
public class ExchangeDestination
{
public readonly string Value;
public readonly double ExchangeFee;
public ExchangeDestination(string Value, double ExchangeFeed)
{
this.Value = Value;
this.ExchangeFee = ExchangeFee;
}
public abstract class ARCA
{
public static ExchangeDestination Only = new ExchangeDestination("ARCA.ONLY", 0.01);
public static ExchangeDestination PostOnly = new ExchangeDestination("ARCA.ONLYP", 0.02);
}
public abstract class NYSE
{
public static ExchangeDestination Only = new ExchangeDestination("NYSE.ONLY", 0.01);
public static ExchangeDestination PostOnly = new ExchangeDestination("NYSE.ONLYP", 0.03);
}
}
public class SecurityType
{
public readonly string Value;
public SecurityType(string Value)
{
this.Value = Value;
}
public static SecurityType Equity = new SecurityType("EQ");
public static SecurityType Option = new SecurityType("OPT");
public static SecurityType Future = new SecurityType("FUT");
}
}
Enums work perfectly for what I am trying to do except it is hard to have multiple properties of an enum value. I considered using Attributes on Enums to set the properties but getting those vs. getting static properties of objects is substantially slower and my application is extremely speed/latency sensitive.
Is there perhaps a better way of accomplishing what I am trying to do?
Thanks in advance for your help!
William

Resources