Попытка создать тесты в Spring Boot - PullRequest
0 голосов
/ 14 июля 2020

У меня есть приложение Spring Boot, использующее базу данных H2, которая следует базовой структуре c, т.е. имеет несколько служб, которые получают и сохраняют данные в репозиториях, а затем имеет контроллеры, которые сопоставляют запросы и вызывают службы. Я создал тесты непосредственно для репозитория, которые работают нормально, но теперь я пытаюсь создать несколько тестов для контроллера, например, для запроса на получение, чтобы он здесь должен был вернуть эти данные. Но я продолжаю получать исключение с нулевым указателем, и я не могу понять, как это исправить ... Пока что в основном это выглядит так. возвращает нулевой указатель, а также несколько других вариантов, которые я пробовал. Я новичок в Spring, поэтому мне кажется, что мне не хватает чего-то очень простого. Любая помощь будет принята с благодарностью.

java.lang.NullPointerException
    at com.Demo.Controller.UserControllerTest.getUsers(UserControllerTest.java:30)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:564)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)

Ответы [ 2 ]

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

Перво-наперво - вы запускаете тест JUnit (4 или 5). Но вы не указываете, что он должен инициализировать контекст приложения Spring.

Итак, если вы используете junit 4, добавьте следующее:

@RunWith(SpringRunner.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {
....

Если вы используете junit 5, тогда он выглядит немного иначе:

@ExtendWith(SpringExtension.class)
@WebMvcTest(UserController.class)
public class UserControllerTest {
...

Еще одна вещь, которую нужно обработать, - это использование UserService. Вы должны убедиться (поместив точку останова или что-то еще в коде контроллера), что ссылка на userService инициализирована и это точно такой же объект, как вы определили в @MockBean UserService userService.

Затем как @ Ume sh упомянул, вам нужно указать ожидание от этой заглушки. Для этого используйте библиотеку mockito, как и в обычных модульных тестах:

Mockito.when(userService.whateverYouCallFromController(/*parameters if any*/)).thenReturn(... whatever you return there ...);

@MockBean аннотация создает mock / stub (с помощью mockito) и помещает его в контекст приложения во время создания spring. контекст приложения. Поскольку вы вызываете его в тестируемом методе контроллера, вы должны указать, что вы ожидаете от него, чтобы он вернул такой вызов, не выполняя фактический бизнес-лог. c позади.

Последнее - вы упомянули H2 в вопрос, но для WebMvcTests он в основном не имеет значения - он создает часть ваших bean-компонентов, относящуюся к веб-уровню, и даже не создает репозитории, в которых вы должны вызывать базу данных.

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

Вы использовали @MockBean для UserService, но вы не заглушили значения UserService:

Ниже приведен простой пример заглушки, вам нужно заглушить метод, который вызывается в userService, иначе будет исключение нулевого указателя быть брошенным.

 @Test
   public void getUsers() throws Exception {
      when(userService.someMethod()).thenReturn("Hello, Mock");
      this.mockMvc.perform(get("/users")).andExpect(status().isOk())
   }
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...