В чем разница между полями и переменными в Java?

«В чем разница между полями и переменными в Java?» — вопрос из категории Java, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

В контексте тестирования на Java (например, при написании unit-тестов с JUnit) важно понимать эти различия для корректной организации тестовых данных.

Поля (fields) класса — это переменные, объявленные на уровне класса. В тестах это часто аннотированные поля (например, @Mock, @InjectMocks, @BeforeEach) или поля для хранения общих тестовых данных.

Локальные переменные существуют только в рамках метода (например, внутри отдельного тестового метода @Test).

Пример в тестовом классе:

import org.junit.jupiter.api.*;
import static org.mockito.Mockito.*;

class PaymentServiceTest {
    // ПОЛЕ КЛАССА: мок-объект, инициализируется для всех тестовых методов
    @Mock
    private PaymentGateway mockGateway;

    // ПОЛЕ КЛАССА: тестируемый сервис, в него будет внедрён мок
    @InjectMocks
    private PaymentService paymentService;

    @BeforeEach
    void setUp() {
        MockitoAnnotations.openMocks(this); // Инициализация моков
    }

    @Test
    void testSuccessfulPayment() {
        // ЛОКАЛЬНАЯ ПЕРЕМЕННАЯ: существует только в этом методе
        String transactionId = "TXN-12345";
        double amount = 100.0;

        // Настройка поведения мока (поле mockGateway)
        when(mockGateway.process(anyDouble())).thenReturn(transactionId);

        // Вызов тестируемого метода (использует поле paymentService)
        String result = paymentService.makePayment(amount);

        // Проверка утверждения
        Assertions.assertEquals(transactionId, result);
        verify(mockGateway).process(amount); // Верификация вызова мока
    }
}

Ключевое для QA: Поля @Mock/@InjectMocks переиспользуются между тестами, но их состояние может сбрасываться в @BeforeEach. Локальные переменные изолированы для каждого теста, что предотвращает нежелательные побочные эффекты.