JUnit: Spring Context больше не позволяет проверять защищенные поля в тестируемом классе из-за bean-прокси - PullRequest
0 голосов
/ 11 сентября 2018

В классе бобов есть поле, защищенное для проверки из его класса тестирования.

@Component
public class UILoggerCleanUp {

    protected long periodMin;

    @Autowired
    public UILoggerCleanUp( @Value("${uilogger.period")  String period) {
        this.periodMin = this.someProcessing(period)
    }
 }

В классе тестирования без использования пружины я могу проверить защищенное поле.

public class UILoggerCleanUpTest {

    private UILoggerCleanUp cleanUp;

    @Before
    public void setUp() {
        cleanUp = new UILoggerCleanUp("1");
    }

    @Test
    public void testConfigReadOK() {
        Assert.assertEquals(cleanUp.periodMin, 1);
    }

}

Здесь не используется Spring.

Бин создается конструктором, контекст не требуется.(Метод PostConstruct также можно вызывать вручную).

Это преимущество использования Autowired для конструктора вместо полей.

Так что здесь можно проверить защищенные поля тестируемого класса.

Но тогда ...

Я хотел проверить, что свойства конфигурации считываются и правильно анализируются внутри UILoggerCleanUp (даже когда странные вещи находятся в файле конфигурации) в поле periodMin.Чтобы иметь возможность вставлять значения из файла свойств, мне нужно активировать Spring Context (добавить @SpringBootTest).

Но в этом случае Spring добавляет прокси-сервер для Бина и защищенные поля, которые мне нужно проверитьвсегда возвращает ноль.

Для правильного обхода прокси мне нужны методы.Поэтому мне нужны открытые (или защищенные) методы для получения значения поля (без непосредственного доступа к полю).

Но я не хочу модифицировать тестируемый класс ради самого теста.

Поэтому я расширяю тестируемый класс и добавляю сюда новые методы.

Все это только потому, что активация Spring Context больше не позволяет проверять защищенные поля в тестируемом классе :(

@Component
@Profile("test")
class MyUILoggerCleanUp extends UILoggerCleanUp {

     @Autowired
     public MyUILoggerCleanUp( @Value("${uilogger.period}")  String configPeriodMin) {
        super(configPeriodMin);
     }

     protected long getPeriodMin() {
         return super.periodMin;
     }
 }

 @RunWith(SpringRunner.class)
 @SpringBootTest
 @ActiveProfiles({"test"})
 public class UILoggerCleanUpTest2 {

      @Autowired
      private MyUILoggerCleanUp cleanUp;

      @Test
      public void testConfigReadOK() {
          Assert.assertEquals(cleanUp.getPeriodMin(), 1);
      }
 } 

Это работает!

Но какое-то громоздкое решение.

Есть ли более чистое решение?

Является ли Springпредлагая что-то для этого случая?

ОБНОВЛЕНИЕ

Ну, я мог бы переместить защищенный метод в тестируемом классе:

  • Я изменяю тестируемый класс для теста, но он все еще не является общедоступным API. (Если тестируемый класс не мой - как класс третьей стороны - это невозможно)

  • больше не нужно дляподкласс

  • , если вы заранее предоставите такой методods - это как подготовка тестируемого класса к тестированию в Spring Context (на всякий случай)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...