2016-10-21 4 views
2

Следующий фрагмент кода достаточно, чтобы воспроизвести мою проблему:тест CdiUnit с JUnit @Rule невозможно из-за публичного частного поля парадокс

  • Либо я установить thrown атрибут public и получить ошибку org.jboss.weld.exceptions.DefinitionException: WELD-000075: Normal scoped managed bean implementation class has a public field
  • Или Я удалить модификатор public и получить ошибку org.junit.internal.runners.rules.ValidationError: The @Rule 'thrown' must be public.
  • Я также попытался позволить public модификатора на месте и добавить объем @Dependent аннотаций на классе, но получил ошибку org.jboss.weld.exceptions.DefinitionException: WELD-000046: At most one scope may be specified on [EnhancedAnnotatedTypeImpl] public @Dependent @ApplicationScoped @RunWith

Я удалил все ненужные коды, но это довольно сложный модульный тест с макетами, инжекцией службы через CDI и некоторыми методами тестирования, которые, как ожидается, вызовут исключение.

import org.jglue.cdiunit.CdiRunner; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.ExpectedException; 
import org.junit.runner.RunWith; 

@RunWith(CdiRunner.class) 
public class FooBarTest { 

    @Rule 
    public ExpectedException thrown = ExpectedException.none(); 

    @Test 
    public void test() { 

    } 
} 

Так что моя проблема заключается в том, что с одной стороны сварного шва хочет, чтобы все поля, чтобы не быть открытыми, потому что она не сможет Proxify класс иначе, а с другой стороны, JUnit хотим Правилу поля должны быть открытыми, потому что ему использует отражение для доступа к ним и не хочет использовать метод setAccessible(true) из-за того, что активен менеджер безопасности. Как бороться с этим парадокс?

NB: Я также нашел намек комментарии this answer, заявив, что

Вы также можете аннотировать метод с @Rule, так что это позволило бы избежать проблемы

Но я не удалось найти любой пример теста junit с аннотацией @Rule по методу, я планирую задать отдельный вопрос об этом.

ответ

9

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

import org.jglue.cdiunit.CdiRunner; 
import org.junit.Rule; 
import org.junit.Test; 
import org.junit.rules.ExpectedException; 
import org.junit.runner.RunWith; 


@RunWith(CdiRunner.class) 
public class FooBarTest { 

    private ExpectedException thrown = ExpectedException.none(); 

    @Rule 
    public ExpectedException getThrown() { 
     return thrown; 
    } 

    @Test 
    public void test() { 
     thrown.expect(ArithmeticException.class); 
     int i = 1/0; 
    } 
} 
+0

Очень приятно. Я бы порекомендовал повысить повышение с помощью команды CdiUnit, они не обязательно должны делать тесты '@ ApplicationScoped'. –

+0

Хорошая идея, но работает только частично. Вы не можете использовать правило для предоставления вещей для тестирования с помощью @Produces, потому что производители CDI вызываются до применения правил. :( – Gandalf

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