Spring boot @Autowired не работает в модульном тестовом случае - PullRequest
1 голос
/ 11 июля 2020

Насколько я понимаю, если мы используем стереотипы Spring, нам не нужно использовать ключевое слово new для создания экземпляра. Spring управляет этим за нас и предоставляет нам bean-компоненты во время выполнения.

И для того, чтобы Spring мог внедрить эти bean-компоненты, нам нужно использовать аннотацию @Autowired там, где мы хотим, чтобы Spring внедрил этот bean-компонент. Ниже у меня очень простой класс, в котором я использую @Component, чтобы Spring справился с этим. В этом классе есть один список, который я инициализирую под свою ответственность, а затем небольшой метод, который выполняет некоторые логические операции c.

@Slf4j
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class Parser {

    private List<String> strList = new ArrayList<>();

    public void parseStrings(final String[] strs) {

        Arrays.stream(strs)
                .map(String::toLowerCase)
                .filter(str -> str.length() > 8)
                .filter(str -> str.endsWith("sam"))
                .forEach(sam1 ->  { strList.add(sam1); });
    }

}

Я также написал один модульный тест для проверки этого, и вот он.

import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.beans.factory.annotation.Autowired;
import static org.junit.jupiter.api.Assertions.*;
@RunWith(MockitoJUnitRunner.class)
class ParserTest {

   @Autowired
   private Parser parser;

    @Test
    void parseStrings() {
        String str[] = {"abcsamsam", "abcsyjhgfed abdul sam","abcAhgbkgdjhul samad", "abcabjhgdulsamsam", "sa"};
        parser.parseStrings(str);

        assertTrue(parser.getStrList().size() == 3);
        assertTrue(parser.getStrList().get(0).equalsIgnoreCase("abcsamsam"));

    }
}

Тест не проходит с

java.lang.NullPointerException, когда он пытается вызвать метод parseStrings, что означает, что он не может ввести надлежащий инициализированный bean-компонент во время выполнения.

Может ли кто-нибудь помочь мне в том, чего мне не хватает? Нужно ли добавлять конструкторы (которые здесь я делаю с использованием аннотаций ломбока) при использовании стереотипов Spring в классе.

Ответы [ 5 ]

1 голос
/ 12 июля 2020

Зачем вам вообще нужен MockitoJUnitRunner здесь? Парсер не имеет зависимостей. Достаточно простой инициализации в тесте. Просто инициализируйте парсер вместо использования аннотации. @SpringBootTest предназначен для интеграционных тестов. Он включает контекст Spring и делает ваш модульный тест медленным и громоздким.

0 голосов
/ 11 июля 2020

Это должно работать:

@SpringBootTest
@RunWith(SpringRunner.class)
class ParserTest {

   @Autowired
   private Parser parser;

    @Test
    void parseStrings() {
        String str[] = {"abcsamsam", "abcsyjhgfed abdul sam","abcAhgbkgdjhul samad", "abcabjhgdulsamsam", "sa"};
        parser.parseStrings(str);

        assertTrue(parser.getStrList().size() == 3);
        assertTrue(parser.getStrList().get(0).equalsIgnoreCase("abcsamsam"));

    }
}
0 голосов
/ 11 июля 2020

SpringBoot2, вы можете использовать аннотацию: @ SpringBootTest для выполнения модульного теста.

как показано ниже:

@SpringBootTest
class DemoApplicationTests {
   
    @Test
    void contextLoads() {
    }

}
0 голосов
/ 11 июля 2020

Я не вижу созданных имитаций, поэтому почему вы используете @RunWith(MockitoJUnitRunner.class)?

Я также видел ответы, рекомендующие использовать @SpringBooTest. Эта аннотация загружает весь контекст вашего приложения в основном для интеграционных тестов, чтобы интегрировать различные уровни приложения. Это также означает, что здесь нет насмешек. Вам это действительно нужно? (Я так не думаю, раз уж вы говорите о модульном тесте)

Если ваш синтаксический анализатор не ссылается на какой-либо другой Bean (который нужно высмеивать), то вы находитесь в случае простого модульного теста.

@RunWith(SpringRunner.class) // you can even removed it 
class ParserTest {

private Parser parser;

@Before
public void setUp() {
     parser = new Parser();

}

    @Test
    void parseStrings() {
        String str[] = {"abcsamsam", "abcsyjhgfed abdul sam","abcAhgbkgdjhul samad", "abcabjhgdulsamsam", "sa"};
        parser.parseStrings(str);

        assertTrue(parser.getStrList().size() == 3);
        assertTrue(parser.getStrList().get(0).equalsIgnoreCase("abcsamsam"));

    }
0 голосов
/ 11 июля 2020

Spring Autowire, если вы запускаете тестовый пример с SpringRunner. Поэтому измените тестовый класс следующим образом.

@RunWith(SpringRunner.class)
class ParserTest {

}

Чтобы ответить на ваш второй вопрос, нет, нет необходимости добавлять no-argument constructor, если только у вас также есть parameterised constructor в том же классе. В этом случае вам нужно явно добавить конструктор без аргументов.

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