Тест 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;
    }
}
Другие вопросы по тегам