Log4j2 Mock Appender - java

I have a class in which I take all of my Properties, and hide their passwords before logging.
#Override
public void afterPropertiesSet() throws Exception {
Properties loadedProperties = this.mergeProperties();
loadedProperties.entrySet().stream().forEach(singleProperty -> {
String key = singleProperty.getKey().toString();
String value = HIDDEN_VALUE;
if (!Arrays.stream(PASSWORD_PATTERNS).anyMatch(pattern -> key.toLowerCase().contains(pattern))) {
value = singleProperty.getValue().toString();
}
logger.info("LoadedProperty: "+ key +"=" + value);
});
}
I have migrated to log4j2 and would like to test this class, checking the output of log4j2. It currently uses log4j and works, however when I migrated to log4j2, I get
Wanted but not invoked:
mockAppender.append();
-> at com.comp.spmConf.ExceptionLoggerTest.verifyErrorMessages(ExceptionLoggerTest.java:87)
However, there were other interactions with this mock:
mockAppender.getName();
-> at org.apache.logging.log4j.core.config.AbstractConfiguration.addLoggerAppender(AbstractConfiguration.java:675)
mockAppender.getName();
-> at org.apache.logging.log4j.core.config.AppenderControl.(AppenderControl.java:51)
Here is my log4j1 test class:
import org.apache.log4j.Appender;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Properties;
#RunWith(MockitoJUnitRunner.class)
public class SpmPropertyTracerTest {
#Mock
private Appender appenderMock;
#Captor
private ArgumentCaptor captorLoggingEvent;
private SpmPropertyTracer tracer;
#Before
public void setup() {
LogManager.getRootLogger().addAppender(appenderMock);
tracer = new SpmPropertyTracer();
}
#After
public void teardown() {
LogManager.getRootLogger().removeAppender(appenderMock);
}
#Test
public void printPropertiesTest() throws Exception{
String key1 = "Foo";
String val1 = "True";
Properties properties = new Properties();
properties.setProperty(key1, val1);
tracer.setProperties(properties);
String expectedString = String.format("LoadedProperty: %s=%s", key1, val1);
tracer.afterPropertiesSet();
Mockito.verify(appenderMock).doAppend((LoggingEvent)captorLoggingEvent.capture());
LoggingEvent loggingEvent = (LoggingEvent) captorLoggingEvent.getValue();
assert expectedString.equals(loggingEvent.getRenderedMessage());
}
}
And here is my log4j2 test class, am I doing something wrong in the log4j to log4j2 migration?
import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.Properties;
import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;
#RunWith(MockitoJUnitRunner.class)
public class TestClass {
#Mock
private Appender mockAppender;
#Captor
private ArgumentCaptor<LogEvent> captorLoggingEvent;
private SpmPropertyTracer tracer;
private Logger logger;
private LogEvent logEvent;
#Before
public void setup() {
// prepare the appender so Log4j likes it
when(mockAppender.getName()).thenReturn("MockAppender");
when(mockAppender.isStarted()).thenReturn(true);
when(mockAppender.isStopped()).thenReturn(false);
logger = (Logger)LogManager.getLogger(SpmPropertyTracer.class);
logger.addAppender(mockAppender);
logger.setLevel(Level.INFO);
tracer = new SpmPropertyTracer();
}
#After
public void tearDown() {
// the appender we added will sit in the singleton logger forever
// slowing future things down - so remove it
logger.removeAppender(mockAppender);
}
#Test
public void loggingIsCaptured() throws Exception {
String key1 = "Foo";
String val1 = "True";
Properties properties = new Properties();
properties.setProperty(key1, val1);
tracer.setProperties(properties);
String expectedString = String.format("LoadedProperasdfty: %s=%s", key1, val1);
tracer.afterPropertiesSet();
verifyErrorMessages(expectedString);
}
// handy function to inspect the messages sent to the logger
private void verifyErrorMessages(String ... messages) {
verify(mockAppender, times(messages.length)).append((LogEvent)captorLoggingEvent.capture());
int i=0;
for(LogEvent loggingEvent:captorLoggingEvent.getAllValues()) {
assertEquals(messages[i++], loggingEvent.getMessage().getFormattedMessage());
}
}

The parent project was brining in a log4j dependency, thus slf4j was binding with log4j and not log4j2 and that is why the append method was not invoked. Removing that dependency fixed my errors.

Related

How to test Aspects

I have found and tried to follow this answer by Roman Puchkovskiy with a detailed example, but I am missing some detail.
Here is the aspect I am trying to test:
package com.company.reporting.logger.consumer.prometheusmetrics;
import io.micrometer.core.instrument.Counter;
import io.micrometer.core.instrument.MeterRegistry;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.kafka.KafkaException;
import org.springframework.stereotype.Component;
#Aspect
#Component
#Slf4j
/**
* AOP Class to capture error count due to kafka exception
*/
public class MetricsCollection {
MeterRegistry meterRegistry;
private final Counter counter;
public MetricsCollection(MeterRegistry meterRegistry) {
this.meterRegistry = meterRegistry;
counter = Counter.builder("Kafka.producer.error.count").description("Custom Kafka Producer metrics for business exception").tags("behavior", "exception").register(meterRegistry);
}
/***
* point cut for jointPoint within service class execution
*/
#Pointcut("within (#org.springframework.stereotype.Service *)")
public void serviceBean() {
// this is pointcut
}
/***
* point cut for all the jointPoints
*/
#Pointcut("execution(* *(..))")
public void methodPointcut() {
// this is pointcut
}
/***
*
* increasing counter upon kafka exception
*/
#AfterThrowing(pointcut = "serviceBean() && methodPointcut()", throwing = "e")
public void handleException(Exception e) {
if (e instanceof KafkaException || e instanceof org.apache.kafka.common.KafkaException) {
LOGGER.error("*** In Aspect ErrorHandler *** " + e.getLocalizedMessage());
counter.increment();
}
}
}
And here is my unit test class:
package com.company.reporting.logger.consumer.prometheusmetrics;
import com.company.reporting.logger.consumer.utils.TestUtils;
import java.util.List;
import static org.junit.jupiter.api.Assertions.*;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import io.micrometer.core.instrument.MeterRegistry;
import io.micrometer.core.instrument.composite.CompositeMeterRegistry;
import org.apache.kafka.common.KafkaException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.MockitoAnnotations;
import org.springframework.aop.aspectj.annotation.AspectJProxyFactory;
import org.springframework.aop.framework.AopProxy;
import org.springframework.aop.framework.DefaultAopProxyFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Controller;
class MetricsCollectionTest {
private MetricsCollection aspect;
private TestController controllerProxy;
MeterRegistry meterRegistry;
#BeforeEach
void setUp() {
MockitoAnnotations.openMocks(this);
meterRegistry = new CompositeMeterRegistry();
aspect = new MetricsCollection(meterRegistry);
AspectJProxyFactory aspectJProxyFactory = new AspectJProxyFactory(new TestController());
aspectJProxyFactory.addAspect(aspect);
DefaultAopProxyFactory proxyFactory = new DefaultAopProxyFactory();
AopProxy aopProxy = proxyFactory.createAopProxy(aspectJProxyFactory);
controllerProxy = (TestController) aopProxy.getProxy();
}
#Test
void MetricsCollection() {
MetricsCollection metricsCollection = new MetricsCollection(meterRegistry);
assertNotNull(metricsCollection);
}
#Test
void handleException() {
ListAppender<ILoggingEvent> listAppender = TestUtils.getiLoggingEventListAppender(MetricsCollection.class);
try {
controllerProxy.throwKafkaException();
} catch (Exception ex) {
if (! (ex instanceof KafkaException)) {
fail();
}
} finally {
List<ILoggingEvent> logList = listAppender.list;
assertEquals(1, logList.size());
}
}
#Controller
static
class TestController {
#Bean
String throwKafkaException() {
throw new KafkaException();
}
}
}
Finally, here is my TestUtils class:
package com.company.reporting.logger.consumer.utils;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.read.ListAppender;
import org.slf4j.LoggerFactory;
public class TestUtils {
#NotNull
public static ListAppender<ILoggingEvent> getiLoggingEventListAppender(Class clazz) {
Logger logger = (Logger) LoggerFactory.getLogger(clazz);
ListAppender<ILoggingEvent> listAppender = new ListAppender<>();
listAppender.setName(clazz.getName());
listAppender.start();
logger.addAppender(listAppender);
return listAppender;
}
}
My constructor test passes... :)
But the handleException() test is failing to trigger my aspect. Which dot on an i or cross bar on a t did I miss?
Your "unit test" is closer to an integration test, and you are testing the AOP framework more than the aspect itself. The only thing you do seem to test is the side effect of logging, which is a topic unrelated to AOP. For other ways to unit-test or integration-test aspects, see my linked answers.
Apart from that and without having tried to copy and compile your code yet, what immediately strikes me as odd is that your aspect has a within (#org.springframework.stereotype.Service *) pointcut, but your target class seems to be a #Controller. I would not expect the aspect to match there. What happens if you fix that?

BaggageField updateValue method returns false in jUnit tests

EDIT: One problem was that Tracing.current() was null. I fixed this with the new #BeforeEach instead of the old #BeforeTestMethod:
Tracer tracer;
#BeforeEach
void init() {
tracer = Tracing.newBuilder().build().tracer();
TraceContext ctx = TraceContext.newBuilder().traceId(17).spanId(17).build();
Span span = tracer.toSpan(ctx);
tracer.withSpanInScope(span);
}
Yet, updateValue still doesn't work as there are no extras in the context, so nothing to update...
Following the ideas like in those answers, I'm trying to use BaggageFields in one of my tests. All the objects are not null, but updateValue returns false and the test fails with BaggageTest.baggageTest:40 expected: <hello> but was: <null>. As said, I have no idea why the updateValue method is not working.
import static org.junit.jupiter.api.Assertions.assertEquals;
import brave.baggage.BaggageField;
import brave.baggage.CorrelationScopeConfig;
import brave.context.slf4j.MDCScopeDecorator;
import brave.propagation.CurrentTraceContext;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.sleuth.ScopedSpan;
import org.springframework.cloud.sleuth.Tracer;
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.event.annotation.BeforeTestMethod;
import org.springframework.test.context.junit.jupiter.SpringExtension;
#Slf4j
#ExtendWith(SpringExtension.class)
#ContextConfiguration
public class BaggageTest {
#Autowired
ApplicationContext context;
#BeforeTestMethod
void init() {
Tracer tracer = context.getBean(Tracer.class);
ScopedSpan span = tracer.startScopedSpan("test");
}
#Test
void baggageTest() {
BaggageField fooBar = context.getBean("fooBar", BaggageField.class);
log.info("updateValue {}", fooBar.updateValue("hello"));
assertEquals("hello", fooBar.getValue());
}
#Configuration
static class Config {
private BaggageField findOrCreate(String name) {
BaggageField field = BaggageField.getByName(name);
if (field == null) {
field = BaggageField.create(name);
}
return field;
}
#Bean("fooBar")
BaggageField fooBar() {
return findOrCreate("fooBar");
}
#Bean
CurrentTraceContext.ScopeDecorator mdcScopeDecorator() {
return MDCScopeDecorator.newBuilder()
.clear()
.add(CorrelationScopeConfig.SingleCorrelationField.newBuilder(fooBar())
.flushOnUpdate()
.build())
.build();
}
}
}
My solution is to manually build the TraceContext, using the following snippet, being careful that BaggageFields is brave.internal.baggage.BaggageFields.
#Autowired
BaggageField field;
Tracer tracer;
#BeforeEach
void init() {
tracer = Tracing.newBuilder().build().tracer();
ArrayList<BaggageField> list = new ArrayList<>();
list.add(field);
TraceContext ctx = TraceContext.newBuilder()
.addExtra(BaggageFields.newFactory(list,2).create())
.traceId(17).spanId(17).build();
Span span = tracer.toSpan(ctx);
tracer.withSpanInScope(span);
}

How to unit-test a class which has methods using database connection?

I am trying to run tests on a controller class and it has atleast a method which internally uses a DAO to retrieve information from the DB (MySQL).
The problem I have is that the dao method is giving null and I end up with NullPointerException error.
How do I tests a class which has methods that internally use a database connection?
Haven't been able to find any useful post/answer.
Project structure:
src
main
java
[package]
RegisterController.java
Config.java // configuration class
test
java
[package]
RegisterControllerTest.java
RegisterController.java
package com.webapp.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import com.webapp.Config;
import com.webapp.dao.AccountDao;
#Controller
public class RegisterController {
#Autowired
AccountDao accDao;
public String validateUsername(String uname){
List<String> errors = new ArrayList<String>();
// ... unrelated code
// NullPointerException thrown here
if(accDao.getAccountByUsername(uname) != null)
errors.add("err#taken");
return errors.toString();
}
}
RegisterControllerTest.java
import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.springframework.boot.test.context.SpringBootTest;
import com.webapp.controller.RegisterController;
import com.webapp.Config;
#SpringBootTest
public class RegisterControllerTest {
#Mock
private Config config;
private RegisterController rc;
#BeforeEach
public void init() {
config = Mockito.mock(Config.class);
rc = new RegisterController();
}
#Test
public void testValidateUsername() {
assertEquals("[]", rc.validateUsername("Username123")); // N.P.E
}
}
Config.java
package com.webapp;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import com.webapp.dao.AccountDao;
import com.webapp.dao.AccountDaoImpl;
import com.webapp.dao.Dao;
#Configuration
#ComponentScan(basePackages = { "com.webapp.controller", "com.webapp.dao", "com.webapp.test" })
public class Config {
private static class Database {
private static String host = "127.0.0.1";
private static String user = "root";
private static String pass = "root";
private static String dbname = "memedb";
private static int port = 3306;
public static String getUrl() {
return "jdbc:mysql://"+host+":"+port+"/"+dbname+"?serverTimezone=Europe/Stockholm";
}
}
#Bean
public DriverManagerDataSource getDataSource() {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.cj.jdbc.Driver");
ds.setUrl(Database.getUrl());
ds.setUsername(Database.user);
ds.setPassword(Database.pass);
return ds;
}
#Bean
public AccountDao getAccDao() {
return new AccountDaoImpl(getDataSource());
}
}
Instead of mocking config, mock the Dao. You are getting NPE, because the mocked config is not setting #Autowired accDao... so your accDao == null:
#Controller
public class RegisterController {
AccountDao accDao;
public RegisterController(AccountDao accDao) {
this.accDao = accDao;
}
...
}
#BeforeEach
public void init() {
accDaoMock = Mockito.mock(AccountDao.class);
rc = new RegisterController(accDaoMock);
}
#Test
public void testValidateUsername() {
when(accDaoMock.getAccountByUsername("Username123")).thenReturn(null);
assertEquals("[]", rc.validateUsername("Username123"));
}
Why are you configuring the connection DB programmatically? I advise you configure the connection DB with autoconfiguration of Spring Boot.
The DAO object have to mock in an unit test.
Here is a good article about the Junit test for a Spring Boot App.

JUnit Testing FaceContext and Session Code

I am attempting to Junit test (IDE: Intellij) Method inside a class called "ManagementDashboardBean" called: (Method name): init()
The method contains FaceContext and Session. I tried the following: https://codenotfound.com/mockito-unit-testing-facescontext-powermock-junit.html
but am still running into issues. I am using Mockito and PowerMockito to help but cannot figure out my init() is saying Null Pointer Exception (NPE). Any guidance would be greatly appreciated. Thanks
P.S the end goal is to show proper test code coverage of this method.
public void init() {
FacesContext context = FacesContext.getCurrentInstance();
HttpSession session = (HttpSession)context.getExternalContext().getSession(false);
userInfo = (UserSessionInfo)session.getAttribute(ConstantsUtil.USER_INFO);
startDt = FDUtil.toDate(FDUtil.toStartOfMonth(userInfo.getCurrentDateMillis()));
endDt = FDUtil.toDate(FDUtil.toEndOfMonth(userInfo.getCurrentDateMillis()));
autoCompleteDate = false;
}
Current JUnit Test
package view.managed.core;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import javax.faces.application.FacesMessage;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.servlet.http.HttpSession;
import com.sun.jdi.connect.Connector;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Mock;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
#RunWith(PowerMockRunner.class)
#PrepareForTest({FacesContext.class})
public class ManagementDashboardBeanTest {
private ManagementDashboardBean someBean;
#Mock
private FacesContext facesContext;
#Mock
private ExternalContext externalContext;
#Before
public void setUp() throws Exception {
someBean = new ManagementDashboardBean();
//mock all static methods of FaceContext using PowerMockito
PowerMockito.mockStatic(FacesContext.class);
when(FacesContext.getCurrentInstance()).thenReturn(facesContext);
when(facesContext.getExternalContext()).thenReturn(externalContext);
}
#Test
public void testInitContext() {
//create Captor instances for the userInfo
// ArgumentCaptor<String> clientIdCapture = ArgumentCaptor.forClass(String.class);
// ArgumentCaptor<HttpSession> session = ArgumentCaptor.forClass(HttpSession.class);
// Run the method being tested
// someBean.init();
// verify(facesContext).addMessage(clientIdCapture.capture(), (FacesMessage) session.capture());
}
}
The actual .java source file starts with:
public class ManagementDashboardBean extends EntityManagerService implements Serializable {
private static final Logger LOG = LoggerFactory.getLogger(ManagementDashboardBean.class);
The right after is this, which confuses the hell out of me:
public ManagementDashboardBean() {
init();
}
What I have added so far:
import static org.junit.Assert.*;
import javax.faces.context.FacesContext;
import mil.af.fd.view.managed.services.EntityManagerService;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;
import org.powermock.core.classloader.annotations.PrepareForTest;
import java.io.Serializable;
#RunWith(MockitoJUnitRunner.class)
#PrepareForTest({FacesContext.class})
public class ManagementDashboardBeanTest {
private ManagementDashboardBean dashboard;
private Serializable serializableMock;
private EntityManagerService entityManagerServiceMock;
#BeforeClass
public static void before() {
System.out.println("Before Class");
}
#Before
public void setUp() throws Exception {
entityManagerServiceMock = Mockito.mock(EntityManagerService.class);
serializableMock = Mockito.mock(Serializable.class);
dashboard = new ManagementDashboardBean(serializableMock);
}
#Test
public void testInitContext() {
// dashboard.init();
System.out.println("Test 1");
}
}

Mocked EhCache NullPointerException in JUnit 5 test

I am writing Unit tests for a service I want to test. Several methods try to retrieve values from an EhCache.
I tried mocking them with Mockito and simply have the get(String key) method of Cache return null, since I want to ignore the caching for these tests.
My test class:
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyList;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Resource;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import com.jysk.dbl.esldataservice.model.Preis;
import com.jysk.dbl.esldataservice.service.PreisService;
import com.jysk.dbl.esldataservice.service.external.PimDataService;
import com.jysk.dbl.esldataservice.service.external.SapCarService;
import net.sf.ehcache.Cache;
import net.sf.ehcache.CacheManager;
public class PreisServiceTest {
#Mock
private SapCarService sapCarService;
#Mock
private ArticleDataService articleDataService;
#Mock
private CacheManager cacheManager;
#Mock
private Cache cache;
#InjectMocks
#Resource
private PreisService preisService;
#BeforeEach
public void setup() {
MockitoAnnotations.initMocks(this);
when(this.cacheManager.getCache(anyString())).thenReturn(this.cache);
when(this.cache.get(anyString())).then(null);
}
protected static final String TEST_STORE_IDENTIFIER = "1234";
private static final String ARTICLE_IDENTIFIER_1 = "12345001";
private static final String ARTICLE_IDENTIFIER_2 = "54321001";
private final Preis p1 = new Preis(ARTICLE_IDENTIFIER_1, 10.00, 15.00, "01", "01", "01");
private final Preis p2 = new Preis(ARTICLE_IDENTIFIER_2, 20.00, 25.00, "02", "02", "02");
#Test
void testGetPreisReturnsOneCorrectPreis() {
when(this.sapCarService.getPreise(Arrays.asList(ARTICLE_IDENTIFIER_1), TEST_STORE_IDENTIFIER, true)).thenReturn(Arrays.asList(this.p1));
final List<Preis> actual = this.preisService.getPreis(ARTICLE_IDENTIFIER_1, TEST_STORE_IDENTIFIER);
verify(this.sapCarService, times(1)).getPreise(anyList(), anyString(), anyBoolean());
assertNotNull(actual);
assertEquals(1, actual.size());
assertEquals(this.p1, actual);
}
}
My implementation:
private Preis searchPreisInCache(String key) {
final Element preisOptional = this.cacheManager.getCache("preis").get(key); // NPE here
if (preisOptional != null) {
final Preis preis = (Preis) preisOptional.getObjectValue();
logger.info(String.format("Preis with key '%s' found in cache 'preis'.", key));
return preis;
}
return null;
}
The stackTrace showed, that the NPE gets thrown inside the net.sf.ehcache.Cache class:
public final Element get(Object key) throws IllegalStateException, CacheException {
getObserver.begin(); // NPE thrown here
checkStatus();
if (disabled) {
getObserver.end(GetOutcome.MISS_NOT_FOUND);
return null;
}
Element element = compoundStore.get(key);
if (element == null) {
getObserver.end(GetOutcome.MISS_NOT_FOUND);
return null;
} else if (isExpired(element)) {
tryRemoveImmediately(key, true);
getObserver.end(GetOutcome.MISS_EXPIRED);
return null;
} else if (!skipUpdateAccessStatistics(element)) {
element.updateAccessStatistics();
}
getObserver.end(GetOutcome.HIT);
return element;
}
Is there any easy solution for this problem, if I simply want the Cache to return null, whenever it's called?
Mockito can't mock final methods and classes without some configuration. As Morfic pointed out, it is posible with Mockito v2.x, like explained here and here.
Basically, you have to add a text file named org.mockito.plugins.MockMaker under the directory src/test/resources/mockito-extensions with the content mock-maker-inline and tada, Mockito can mock final methods and classes.
However, this uses a different engine with different limitations, so be aware of that.

Categories

Resources