У меня есть примитивный проект Spring-Boot с Junit5 и Lombok. У меня есть простой класс:
public class Calculator {
public int subtract(int a, int b) {
return a - b;
}
}
И создал для него тест:
import lombok.AllArgsConstructor;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
@AllArgsConstructor
class CalculatorTest {
private final Calculator calculator;
private static final int SUBTRACTION_RESULT = 2;
@Test
void subtractTest() {
int result = calculator.subtract(5, 3);
assertEquals(result, SUBTRACTION_RESULT);
}
}
Сбой теста с:
org.junit.jupiter.api.extension.ParameterResolutionException: No ParameterResolver registered for parameter [final com.udemy.junits.Calculator calculator] in constructor [public com.udemy.junits.CalculatorTest(com.udemy.junits.Calculator)].
Насколько я понимаю, он не может инициализировать и создать экземпляр калькулятора. Я попытался сделать это без Ломбока и добавил конструктор:
public CalculatorTest(Calculator calculator) {
this.calculator = calculator;
}
Был такой же результат. Затем я создал это таким образом, используя @BeforeAll:
@BeforeAll
static void init() {
calculator = new Calculator();
}
Это сработало. Внедрение зависимостей здесь недоступно, потому что у нас нет контекста приложения? Или я неправильно понимаю?
Можно ли здесь выполнить внедрение зависимостей без создания экземпляра калькулятора var as new Calculator() ?
Что ты пытаешься сделать? Инициализация объекта калькулятора новым экземпляром Calculator работает нормально.




Ваш последний блок кода правильный и является стандартной практикой, вам не нужен конструктор в этом тестовом классе для экземпляра Calculator.
Для тестового класса вы должны определить поля и инициализировать их методом @BeforeAll или @BeforeEach.
Использование конструктора для тестового класса в JUnit зарезервировано для параметризованных модульных тестов, поэтому вы получаете сообщение об ошибке, указывающее, что вам не хватает ParameterResolver. Это будет пример, когда вы будете использовать конструктор для параметризованного теста:
public class Calculator {
public int subtract(int a, int b) {
return a - b;
}
}
@RequiredArgsConstructor
@RunWith(Parameterized.class)
class CalculatorTest {
private final int x;
private final int y;
private final int z;
private Calculator calculator;
// Constructor is generated by lombok with @RequiredArgsConstructor
// and accepts three parameters, x, y, and z
@BeforeEach
void setUp() {
calculator = new Calculator();
}
@Test
void testSubtract() {
assertEquals(z, calculator.subtract(x, y));
}
/**
* This method will pass each parameter into the constructor
* of this test class. In this case, the testSubtract method
* will be ran 4 times with each set of parameters.
*/
@Parameterized.Parameters
static Collection parameters() {
return Arrays.asList(
new Object[][] {
{5, 3, 2},
{10, 1, 9},
{120, 40, 80},
{1, 1, 0}
}
);
}
}
Вы можете найти дополнительные сведения о параметризованном модульном тестировании здесь для JUnit 4 и здесь для JUnit 5.
В вашем тесте нет ничего, связанного со Spring, так как же Spring узнает, что вы хотите внедрить зависимости в свой тест? Если вам нужен полноценный интеграционный тест, добавьте
@SpringBootTest, иначе добавьте@ExtendWith(SpringExtension.class)и предоставьте@ContextConfiguration... Все это вы также можете найти в отличной документации Spring и Spring Boot.