В классе бобов есть поле, защищенное для проверки из его класса тестирования.
@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 (на всякий случай)