Тест 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() {
}
}
Поэтому моя проблема в том, что, с одной стороны, Weld хочет, чтобы все поля не были общедоступными, потому что в противном случае он не сможет проксифицировать класс, а с другой стороны, JUnit хочет, чтобы поля Rule были открытыми, потому что он использует отражение для доступа к ним и не хочет использовать setAccessible(true)
метод из-за случаев, когда менеджер безопасности активен. Как бороться с этим парадоксом?
NB: я также нашел подсказку комментариев к этому ответу, заявив, что
Вы также можете аннотировать метод с помощью @Rule, чтобы избежать этой проблемы.
Но я не смог найти ни одного примера теста джунит с @Rule
По аннотации на метод я планирую задать отдельный вопрос по этому поводу.
1 ответ
Я узнал, как решить проблему. Для дальнейшего использования, вот фрагмент, который работает, надеюсь, это поможет другим людям.
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;
}
}