2016-01-26 3 views
0

В настоящее время я играю с springockito-annotations, для этого требуются аннотации @RunWith и @ContextConfiguration. Я хотел бы поместить эти аннотации в суперкласс моих тестов, но не могу заставить его работать.@ContextConfiguration не наследуется Springckito

Суперкласс:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) 
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:spring/test-context.xml") 
public class MyTestSuperclass { 
    //... 

Пример TestClass:

public class MyTest extends MyTestSuperclass { 
    @Inject 
    @ReplaceWithMock 
    private MyService myService; 
    //... 

С помощью этого кода, myService не заменен на макет.

Но, если я изменить его ...

@ContextConfiguration 
public class MyTest extends MyTestSuperclass { 
    //... 

... это работает.

Есть ли способ избежать необходимости добавлять @ContextConfiguration ко всем моим тестовым классам? Возможно, это было исправлено в более новой версии Spring/Spring-tests? Из того, что я могу сказать, он может наследовать часть locations из суперкласса без аннотации подкласса, но часть loader не работает без аннотации в подклассе. Я использую версию 3.2.1.RELEASE Spring-test.

Вот пример Projec, который показывает ошибку:

http://www.filedropper.com/springockitobug

+0

'пружинно-test' поддерживает наследование погрузчиков, так как Spring Framework 3.0. Поэтому вам определенно не нужно обновлять пустую '@ ContextConfiguration'. Возможно, проблема с реализацией Springockito. Вы хотели бы опубликовать минимальный примерный проект, чтобы продемонстрировать это поведение (например, на GitHub)? –

+0

Я думаю, что виновником является 'springockito-annotations', у меня также были проблемы, когда у аннотированного класса был не аннотированный суперкласс, в этих случаях' @ ReplaceWithMock' тоже не работал. – Tobb

+0

Добавлен минимальный проект. Не удалось воспроизвести ошибку в приведенном выше комментарии в минимальном проекте, поэтому должно было быть связано с чем-то другим. – Tobb

ответ

2

Это связано с bug in Springockito.

@ContextConfiguration действительно наследуется, что было верно, так как оно было введено весной 2.5. Кроме того, сконфигурированный loader (т. Е. SpringockitoContextLoader в этом случае) также наследуется, что верно с весны 3.0.

Проблема здесь в том, что SpringockitoContextLoader некорректно обрабатывает объявлении класса (то есть класс, который помечается @ContextConfiguration) вместо фактического тестового класса (которые могут быть подклассом, который наследует декларацию @ContextConfiguration).

После тщательной отладки выяснилось, что решение довольно просто (на самом деле проще, чем оригинальная реализация SpringockitoContextLoader).

Следующие PatchedSpringockitoContextLoader должны отлично работать в качестве замены взамен для сломанных SpringockitoContextLoader.

import org.kubek2k.springockito.annotations.internal.Loader; 

import org.springframework.context.ConfigurableApplicationContext; 
import org.springframework.context.support.GenericApplicationContext; 
import org.springframework.test.context.MergedContextConfiguration; 
import org.springframework.test.context.support.GenericXmlContextLoader; 

public class PatchedSpringockitoContextLoader extends GenericXmlContextLoader { 

    private final Loader loader = new Loader(); 

    @Override 
    protected void prepareContext(ConfigurableApplicationContext context, MergedContextConfiguration mergedConfig) { 
     super.prepareContext(context, mergedConfig); 
     this.loader.defineMocksAndSpies(mergedConfig.getTestClass()); 
    } 

    @Override 
    protected void customizeContext(GenericApplicationContext context) { 
     super.customizeContext(context); 
     this.loader.registerMocksAndSpies(context); 
    } 

} 

Привет,

Sam (автор Спринг TestContext Framework)

0

Вместо того, чтобы использовать супер класс, использовать аннотацию.

Например:

@RunWith(SpringJUnit4ClassRunner.class) 
@TestExecutionListeners({ DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class}) 
@ContextConfiguration(loader = SpringockitoContextLoader.class, locations = "classpath:spring/test-context.xml") 
@Target(ElementType.TYPE) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface TestConfiguration { 
} 

Затем аннотирования классы теста с

@TestConfiguration 
public class MyTest { 
    @Inject 
    @ReplaceWithMock 
    private MyService myService; 
    //... 

подсветка синтаксиса в среде IDE может жаловаться не разрешается вводить в зависимости, которые вы используете, но мои первоначальные тесты иметь эту работу

+0

Я стараюсь избегать аннотации каждого тестового класса, изменяя '@ ContextConfiguration' на' @ TestConfiguration', на самом деле это не помогает (если я не могу поставить '@ TestConfiguration' на суперкласс и избегать его в подклассах.) не знал, что это было возможно, полезно знать :) – Tobb

+0

У меня нет рамки класса, настроенной для подтверждения, но вы можете поместить '@ Inherited' в определение' @ TestConfiguration'. Затем поместите это в свой базовый класс - если это работает, просто скажите, и я могу обновить ответ. – Farrell

+1

FYI: '@ RunWith' нельзя использовать _not_ в качестве мета-аннотации. JUnit просто не поддерживается. Таким образом, я не уверен, что вы утверждаете, работает. В вашем примере будет использоваться стандартный бегун 'JUnit4', а не' SpringJUnit4ClassRunner'. –

Смежные вопросы