Использование компонента ThreadPoolTaskExecutor из appconfig в тестовом классе

Я не могу использовать компонент, определенный в конфигурации приложения в классе Service Test, хотя он отлично работает в классе Service. Как использовать компонент для теста? Я могу использовать исполнителей с помощью ReflectionTestUtils немного по-другому, но не так, как с использованием bean-компонентов.

Конфигурация моего приложения выглядит так:

@Configuration
@EnableAsync
@EnableScheduling
public class ApplicationConfiguration {

 @Bean(name = "executor")
  public ThreadPoolTaskExecutor executor(
      @Value("${thread-pool.size}") int size,
      @Value("${thread-pool.shutdownTime}") int shutdownTime) {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(size);
    executor.setMaxPoolSize(size);
    executor.setAwaitTerminationSeconds(shutdownTime);

    executor.initialize();
    return executor;
  }
  
}

Услуга -

public class RandomService {

private ThreadPoolTaskExecutor executor;

public RandomService(@Qualifier("executor") ThreadPoolTaskExecutor executor) {
this.executor = executor;
}

public CompletableFuture<Void> getInfo(DataRequest request) {
return CompletableFuture.runAsync(
            () -> {
              DataResponse dataResponse =
                  getProcessedData(request);
            }, executor)
        .exceptionally(
            ex -> {
             log.error("Exception occurred :: ", ex);
            });
}

}

Тест -

@RunWith(MockitoJUnitRunner.class)
public class randomServiceTest {
@InjectMocks private RandomService randomService;
private ThreadPoolTaskExecutor executor; // How to use the bean defined in appconfig with all values in Test? 

@Before
  public void setUp() throws Exception {
    randomService = new RandomService(executor);
    executor.setCorePoolSize(10); // executor is null here
  }
@Test
  public void testgetInfo() throws Exception {
    randomService.getInfo(request);
  }
}

[Обновление] - Ответ @ Кена Чана помог. У меня есть и другие макеты, но я включил только код, который ранее представлял интерес. Теперь я пытаюсь использовать другой существующий (в кодовой базе) класс TestConfiguration, как показано ниже:

@Configuration
@Profile("test")
public class TestConfiguration {

@Bean(name = "executor")
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(10);
        executor.setAwaitTerminationSeconds(50);
        executor.initialize();
        return executor;
    }
}

Я пытаюсь загрузить этот bean-компонент в контекст Spring в тестовом классе, используя поддержку Spring-тестов, как показано ниже, но все макеты и bean-компонент-исполнитель из тестовой конфигурации имеют значение null и не могут правильно внедриться -

@SpringBootTest
@ExtendWith(SpringExtension.class)
@Slf4j
@ContextConfiguration(classes = TestConfiguration.class)
@ActiveProfiles("test")
public class RandomServiceTest {
@InjectMocks private RandomService randomService;
@MockBean private SomeService someService; //Tried @Mock of Mockito, but it's null
@Autowired private ThreadPoolTaskExecutor executor; // null
@Before
  public void setUp() throws Exception {
    randomService = new RandomService(someService, executor);
  }
}

Может ли кто-нибудь указать на проблему здесь?

Почему это должно быть так? Вы не запускаете там ничего, связанного с Spring, вы используете Mockito для создания экземпляра, поэтому либо создайте его самостоятельно, либо используйте поддержку тестирования Spring, чтобы запустить тест.

M. Deinum 29.09.2023 19:50

когда вы говорите создать экземпляр самостоятельно? как именно это сделать в тесте? В этой статье я следил за внедрением конструктора — coderstower.com/2019/10/07/… т. е. я пробовал без использования аннотации @InjectMocks. Это никогда не назначается, как сейчас.

coder87 29.09.2023 19:55

опять же, почему это должно быть? Я не создаю экземпляры автоматически. Вы используете Spring, поэтому используйте Spring для его запуска. В настоящее время вы используете Mockito. Вы можете просто создать новый экземпляр самостоятельно (new RandomService(yourTaskExecutor))` с исполнителем запроса по вашему выбору. Для этого нет необходимости загружать Spring.

M. Deinum 02.10.2023 07:15
0
3
62
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Если вы просто хотите написать простой тест Junit без запуска контекста Spring, вы можете просто создать ApplicationConfiguration и вызвать executor(), чтобы создать экземпляр ThreadPoolTaskExecutor вручную, например:

public class randomServiceTest {

 private RandomService randomService;
 private ThreadPoolTaskExecutor executor; 

  @Before
  public void setUp() throws Exception {
     ApplicationConfiguration appConfig = new ApplicationConfiguration();
     var executor = appConfig.executor(10,10);
     randomService = new RandomService(executor);
  }

}

Кроме того, поскольку вы не создаете @Mock , нет смысла использовать @InjectMocks вместо @Mock для вставки здесь. Просто подключите все, чтобы все было просто.

Другие вопросы по теме