Mocked bean в весеннем модульном тесте не подключен к зависимости AutoWired

Я пытаюсь написать модульный тест для класса, который имеет зависимость Autowired.

public class User {

@Autowired
private ServiceContext serviceContext;

User() {}

public String getToken() {
    return serviceContext.getToken();
}

Мой класс модульного теста для проверки метода getToken ()

@RunWith(SpringJUnit4ClassRunner.class)
public class UserTest() {

  @MockBean
  private ServiceContext serviceContext;

  @BeforeTest
  private void setup() {
  when(serviceContext.getToken()).thenReturn("Token");
  }

  @Test
  public void test() {
  User user = new User();
  assertEquals(user.getToken(), "Token");
  }
}

Когда я запускаю этот тест, в getToken() из User возникает исключение NullPointerException. Он говорит, что переменная serviceContext равна нулю.

Почему фиктивный bean-компонент, который я создал в тесте, не может быть автоматически подключен к зависимости в классе User?

Я также пробовал этот тестовый код -

@RunWith(SpringJUnit4ClassRunner.class)
public class UserTest() {

  @MockBean
  private ServiceContext serviceContext;

  @InjectMocks
  User useer = new User();

  @BeforeTest
  private void setup() {
  when(serviceContext.getToken()).thenReturn("Token");
  }

  @Test
  public void test() {
  assertEquals(user.getToken(), "Token");
  }
}

Это также дает исключение NullPointerException, говорящее о том, что зависимость serviceContext в классе User равна нулю.

Как выполнить модульное тестирование моих методов класса User с помощью bean-компонента mocked ServiceContext и связать его с объектами User?

Я использую конфигурацию пружины на основе аннотаций и не хочу запускать контейнер Spring, чтобы проверить это.

Для запуска моего приложения я использую это -

@Configuration
@EnableConfigurationProperties(ApiProperties.class)
public class ServiceConfiguration {

  @Bean
  @Scope(value = ConfigurableBeanFactory.SCOPE_SINGLETON, proxyMode = ScopedProxyMode.TARGET_CLASS)
  ServiceContext serviceContext(ApiProperties properties, Parameter param) {
    final ServiceContext serviceContext = new ServiceContext(properties, param);
    return serviceContext;
  }

Мне нужно добавить этот класс в свой @SpringBootTest?


person lostintranslation    schedule 11.09.2019    source источник


Ответы (1)


Как Spring узнает, какой контекст нужно создать?

Вы только определили, что тест должен выполняться с использованием Spring, но Spring не знает, откуда загружать конфигурации.

Вы должны использовать аннотацию @SpringBootTest, если хотите полагаться на правила разрешения конфигурации весенней загрузки, или на некоторое @ContextConfiguration, чтобы вручную указать конфигурации для загрузки.

person Mark Bramnik    schedule 11.09.2019
comment
Я новичок в весне. Не могли бы вы поделиться некоторыми советами о том, что мне следует использовать в качестве классов в @SpringBootTest или @ContextConfiguration? - person lostintranslation; 11.09.2019
comment
Вы действительно должны прочитать об этом, это обширная тема, выходящая далеко за рамки формата SO. В двух словах, это способ указать, что именно должно быть загружено (пружина должна каким-то образом разрешать bean-компоненты). Для начала попробуйте @SpringBootTest без параметров. - person Mark Bramnik; 11.09.2019
comment
В общем, вы можете начать читать здесь: docs.spring.io/spring-boot/docs/current/reference/html/ - person Mark Bramnik; 11.09.2019
comment
Итак, у меня есть аннотированный класс конфигурации, который объявляет bean-компонент ServiceContext. Отредактировал мой вопрос с этой частью кода. - person lostintranslation; 11.09.2019
comment
Проще говоря, класс UserTest не является допустимым тестом загрузки Spring, потому что в нем отсутствует одна из аннотаций, которые я упомянул в ответе. Контекст приложения запускается вообще без bean-компонентов (они загружаются из конфигураций, которые не указаны), поэтому Autowire не имеет ничего общего. - person Mark Bramnik; 11.09.2019
comment
Я не могу использовать @SpringBootTest(ServiceConfiguration.class), поскольку он создаст все @Bean, определенные в его классе. Есть ли более простой способ сделать это? - person lostintranslation; 11.09.2019
comment
Что ж, если вам нужен весенний тест, он должен загрузить некоторые компоненты, иначе зачем вообще использовать Spring. Вы можете создать собственную конфигурацию для тестирования, если хотите. Но вы должны указать, какая конфигурация должна быть загружена как минимум, как я сказал выше - person Mark Bramnik; 11.09.2019