Модульное тестирование во время компиляции

Я использую плагин aspectj maven для создания аспектов во время компиляции. Когда я запускаю приложение, экземпляр класса с аннотацией @Advice создается непосредственно перед первым вызовом совета. Например:

@Aspect
public class MyAdviceClass {

    public MyAdviceClass() {
        System.out.println("creating MyAdviceClass");
    }

    @Around("execution(* *(..)) && @annotation(timed)")
    public Object doBasicProfiling(ProceedingJoinPoint pjp, Timed timed) throws Throwable {
        System.out.println("timed annotation called");
        return pjp.proceed();
    }
}

Если у меня есть метод, использующий аннотацию @Timed, «создание MyAdviceClass» будет напечатано при первом вызове этого метода, а «вызванная временная аннотация» будет напечатана каждый раз.

Я хотел бы провести модульное тестирование функциональности совета, издеваясь над некоторыми компонентами в MyAdviceClass, однако не могу этого сделать, потому что MyAdviceClass создается экземпляром AspectJ как раз вовремя, а не через Spring Beans.

Каков наилучший метод модульного тестирования?


person tgrosinger    schedule 12.02.2014    source источник
comment
Обычно модульные тесты включают в себя имитацию внешних зависимостей, но я их не вижу. Я предполагаю, что вы хотите издеваться над некоторыми внешними зависимостями? Или вы хотите поиздеваться над советом?   -  person Taylor    schedule 12.02.2014
comment
Создать экземпляр MyAdviceClass с помощью его конструктора, использовать макеты для ProceedingJoinPoint и Timed?   -  person    schedule 12.02.2014
comment
@Taylor, я исключил их для простоты. @RC., вы правы, что я мог бы протестировать метод doBasicProfiling таким образом, но я также хотел бы проверить, вызывается ли совет, когда я выполняю аннотированный метод.   -  person tgrosinger    schedule 13.02.2014
comment
Самый простой способ - смоделировать внешний аспект аспекта (какой-то сервис/дао/что бы он ни называл), внедрить его и убедиться, что он вызывается так, как вы ожидаете.   -  person Taylor    schedule 13.02.2014
comment
Да, точно. К сожалению, поскольку AspectJ создает экземпляр в первый раз, когда он необходим, а не через Spring Bean, я не могу найти экземпляр, который он создает для выполнения этой инъекции.   -  person tgrosinger    schedule 13.02.2014


Ответы (1)


Я нашел решение и хотел бы опубликовать его для всех, кто сталкивается с этим. Хитрость заключается в использовании factory-method="aspectOf" в вашем определении bean-компонента Spring. Поэтому, используя приведенный выше пример, я бы добавил эту строку в свой applicationContext.xml

<bean class="com.my.package.MyAdviceClass" factory-method="aspectOf"/>

Любой мой модульный тест будет выглядеть примерно так:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:/META-INF/spring/applicationContext.xml")
public class MyAdviceClassTest {
    @Autowired private MyAdviceClass advice;
    @Mock private MyExternalResource resource;

    @Before
    public void setUp() throws Exception {
        initMocks(this);
        advice.setResource(resource);
    }

    @Test
    public void featureTest() {
        // Perform testing
    }
}

Дополнительные сведения доступны здесь .

person tgrosinger    schedule 13.02.2014