Я не могу использовать компонент, определенный в конфигурации приложения в классе 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);
}
}
Может ли кто-нибудь указать на проблему здесь?
когда вы говорите создать экземпляр самостоятельно? как именно это сделать в тесте? В этой статье я следил за внедрением конструктора — coderstower.com/2019/10/07/… т. е. я пробовал без использования аннотации @InjectMocks. Это никогда не назначается, как сейчас.
опять же, почему это должно быть? Я не создаю экземпляры автоматически. Вы используете Spring, поэтому используйте Spring для его запуска. В настоящее время вы используете Mockito. Вы можете просто создать новый экземпляр самостоятельно (new RandomService(yourTaskExecutor))` с исполнителем запроса по вашему выбору. Для этого нет необходимости загружать Spring.
Если вы просто хотите написать простой тест 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 для вставки здесь. Просто подключите все, чтобы все было просто.
Почему это должно быть так? Вы не запускаете там ничего, связанного с Spring, вы используете Mockito для создания экземпляра, поэтому либо создайте его самостоятельно, либо используйте поддержку тестирования Spring, чтобы запустить тест.