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?