Ответ
Да, можно, но это считается антипаттерном. Тестирование части метода напрямую нарушает принцип инкапсуляции и усложняет поддержку тестов.
Правильные подходы:
- Рефакторинг: Выделите тестируемую логику в отдельный (публичный или package-private) метод и тестируйте его.
- Тестирование через публичный контракт: Протестируйте всю логику метода через его публичный API, используя различные входные данные для покрытия всех веток.
- Использование наследования (редко): Сделать метод защищённым (
protected) и переопределить его в тестовом классе для проверки.
Пример с рефакторингом (предпочтительно):
public class OrderProcessor {
public double calculateTotal(Order order) {
double subtotal = calculateSubtotal(order.getItems()); // Выделенная логика
return applyTax(subtotal, order.getTaxRate());
}
// Теперь эту часть можно протестировать отдельно
public double calculateSubtotal(List<Item> items) {
return items.stream().mapToDouble(Item::getPrice).sum();
}
}
// В тестах
@Test
void calculateSubtotal_ReturnsCorrectSum() {
OrderProcessor processor = new OrderProcessor();
List<Item> items = List.of(new Item(10.0), new Item(20.0));
assertEquals(30.0, processor.calculateSubtotal(items));
}
Почему не стоит тестировать приватные методы через рефлексию: Это делает тесты хрупкими, зависимыми от внутренней реализации, и они ломаются при любом рефакторинге названия или сигнатуры метода. Фокус должен быть на тестировании наблюдаемого поведения класса.