簡體   English   中英

如何測試方面

[英]How to test Aspects

我已經找到並嘗試通過 Roman Puchkovskiy 的這個答案通過一個詳細的例子來遵循這個答案,但是我遺漏了一些細節。

這是我要測試的方面:

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();
        }

    }
}

這是我的單元測試 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();
        }
    }

}

最后,這是我的 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;
    }
}

我的構造函數測試通過了...:)

但是 handleException() 測試未能觸發我的方面。 我錯過了 i 或 at 上的哪個點?

您的“單元測試”更接近於集成測試,並且您正在測試 AOP 框架而不是方面本身。 您似乎唯一要測試的是日志記錄的副作用,這是與 AOP 無關的主題。 有關單元測試集成測試方面的其他方法,請參閱我的鏈接答案。

除此之外,還沒有嘗試復制和編譯您的代碼,讓我感到奇怪的是,您的方面有一個within (@org.springframework.stereotype.Service *)切入點,但您的目標 class 似乎是一個@Controller. 我不希望方面與那里匹配。 如果你解決這個問題會怎樣?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM