Spring Batch JUnit 5 JobLauncherTestUtils is not initialized - spring-boot

I am trying to load the JobLauncherTestUtils object in a JUnit 5 and SpringBatchTest annotation. However, it fails to load the application context. All the other autowired beans load successfully, but the JobLauncherTestUtils fails to load. Here is my test configuration, omitting the imports. I tried manually loading it in BeforeAll but then the JobRepository and JobLauncher fail to load. I am only interested in being able to instantiate JobLauncherTestUtils successfully. Please help!
#ExtendWith(SpringExtension.class)
#ExtendWith(MockitoExtension.class)
#SpringBatchTest
#TestExecutionListeners({DependencyInjectionTestExecutionListener.class ,
DirtiesContextTestExecutionListener.class})
#DirtiesContext(classMode = DirtiesContext.ClassMode.AFTER_CLASS)
#EnableAutoConfiguration
public class ProductsProcessorTest {
#Autowired
JobLauncherTestUtils jobLauncherTestUtils;
#Autowired
private JobRepositoryTestUtils jobRepositoryTestUtils;
#MockBean
JobLauncher jobLauncher;
#Autowired
JobRepository jobRepository;
#Autowired
OrderManagementService orderManagementService;
#MockBean
Job keyLoaderJob;
#Autowired
#JobScope
static ProductsLoader productsLoader;
//Tried manually instantiating it, but then would l
#BeforeAll
static void setUp() throws Exception {
//jobLauncherTestUtils = new JobLauncherTestUtils();
}
//This does not work either
#BeforeEach
void init(){
// jobLauncherTestUtils.setJobLauncher(jobLauncher);
// jobLauncherTestUtils.setJobRepository(jobRepository);
}
....
}
Here is the exception I get:
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'jobLauncherTestUtils': Unsatisfied dependency expressed through method 'setJobRepository' parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'org.springframework.batch.core.repository.JobRepository' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

No qualifying bean of type 'org.springframework.batch.core.repository.JobRepository' available
This error means there is no JobRepository bean defined in your test application context. Make sure you import the class where this bean is defined.

Related

#DataJpaTest loads KafkaConfiguration and fails test

#DataJpaTest
class DataJpaVerificationTest {
#Autowired
private JdbcTemplate template;
#Test
public void testTemplate() {
assertThat(template).isNotNull();
}
}
When I run this test I get the following error:
java.lang.IllegalStateException: Failed to load ApplicationContext
Caused by:
org.springframework.beans.factory.UnsatisfiedDependencyException:
Error creating bean with name 'kafkaConfig' defined in file
[***\config\KafkaConfig.class]:
Unsatisfied dependency expressed through constructor parameter 0;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
'org.springframework.boot.autoconfigure.kafka.KafkaProperties'
available: expected at least 1 bean which qualifies as autowire
candidate. Dependency annotations: {}
where KafkaConfig class is a part of my application (app read data from Kafka and saves data to DB) and looks like:
#Configuration
#RequiredArgsConstructor
public class KafkaConfig {
private final KafkaProperties kafkaProperties;
#Bean
public Properties consumerProperties() {
Properties props = new Properties();
props.putAll(this.kafkaProperties.buildConsumerProperties());
return props;
}
}
Based on information that I googled about DataJpaTest annotation:
created application context will not contain the whole context needed
for our Spring Boot application, but instead only a “slice” of it
containing the components needed to initialize any JPA-related
components like our Spring Data repository.
So the question is: why Spring tries to load to the context Kafka specific bean for DataJpaTest?

Spring Testing Unsatisfied depencency NoSuchBeanDefinitionException

When I try to run my tests they all fail becaouse they can't find the bean of one of my classes.
Here are my codes which are used in the context:
The exception I get is this:
Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'testProtoAdminController' : Unsatisfied dependency expressed through constructor parameter 2; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'TestProtoCopyService' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}
TestProtoAdminControllerTest
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = TestProtoAdminController.class)
public class TestProtoAdminControllerTest {
//Some used services
#Before
public void setUp() {
authenticatedMockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#Test
#WithMockUser
public void testCopyProto() throws Exception {
authenticatedMockMvc.perform(post("/api/admin/{id}/copy", 1)
.contentType(MediaType.APPLICATION_JSON)
.content(asJson(new TestProtoBaseVo()))).andExpect(status().isOk());
}
//Some more tests which are not important in this case
TestProtoCopyService
#Service
public class TestProtoCopyServiceImpl implements TestProtoCopyService {
//Other services and repositories I have to use.
//Methods
}
TestProtoCopyService
public interface TestProtoCopyService {
#Transactional
void copyTestProto(long testProtoId, String sourceTenant, String targetTenant);
}
TestProtoAdminController
#RestController
#RequestMapping("/*")
public class TestProtoAdminController {
private TestProtoCopyService testProtoCopyService;
public TestProtoAdminController(TestProtoCopyService testProtoCopyService {
this.testProtoCopyService = testProtoCopyService;
}
When using #WebMvcTest Spring will prepare everything to test your web layer. This doesn't mean all your beans are scanned and are part of this test application context and ready to inject.
In general, you usually mock the service class of your controller with #MockBean and then use Mockito to specify its behavoir:
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = TestProtoAdminController.class)
public class TestProtoAdminControllerTest {
#MockBean
private TestProtoCopyService mockedService
// the rest
#Before
public void setUp() {
authenticatedMockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#Test
#WithMockUser
public void testCopyProto() throws Exception {
authenticatedMockMvc.perform(post("/api/admin/{id}/copy", 1)
.contentType(MediaType.APPLICATION_JSON)
.content(asJson(new TestProtoBaseVo()))).andExpect(status().isOk());
}
If you want Spring Boot to bootstrap the whole application context with every bean consider using #SpringBootTest. With this annotation, you can inject any bean to your application. The downside here is that you need to provide the whole infrastructure (database/queues/etc.) for your test.

Autowiring not working in SpringBoot controller

Hi i was trying to work over an existing SpringBoot application. I created a service class and tried to autowire it in the existing controller, but when trying to build, its failing saying bean injection failed.
Cause: org.springframework.beans.factory.BeanCreationException: Error
creating bean with name 'controller': Injection of autowired
dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private
com.disooza.www.card.dispenser.service.FilaPartnerService
com.disooza.www.card.dispenser.controller.CardDispenserController.FilaPartnerService;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[com.disooza.www.card.dispenser.service.FilaPartnerService] found for
dependency: expected at least 1 bean which qualifies as autowire
candidate for this dependency. Dependency annotations:
{#org.springframework.beans.factory.annotation.Autowired(required=true)}
at
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
Following is my controller class:
#Controller
#RequestMapping(value = "/service")
public class CardController {
private static final Logger LOGGER = LoggerFactory.getLogger(CardController.class);
#Autowired
private CardDao dao;
#Autowired
private PaymentService paymentService;
#Autowired
private FilaPartnerService filaPartnerService;
FilaPartnerService is the newly created interface, and rest all autowires are working fine in this controller.
Interesting thing is when I try to place this service class in any other controller it is working fine. Any help over this issue will be appreciated, since I'm stuck with it.
This is my service interface:
#Service
public interface FilaPartnerService {
RetrievePaymentTokenResponse retrieveXXX(SupplierRequest request);
}
This is the implementation class:
#Component
public class FilaPartnerServiceImpl implements FilaPartnerService {
#Autowired
private RestTemplate restTemplate;
#Autowired
private RetrieveRequestBuilder retrieveRequestBuilder;
#Value("${filaPartner.url}")
private String filaServiceUrl;
#Override
public RetrievePaymentTokenResponse retrieveFilaPaymentToken(SupplierTokenRequest request) {
RetrievePaymentTokenResponse tokenResponse = null;
RetrievePaymentTokenRequest paymentServiceRequest = retrievePaymentTokenRequestBuilder.retrievePaymentTokenRequestBuilder(request);
try {
tokenResponse =
restTemplate.postForObject( FilaServiceUrl, paymentServiceRequest, RetrievePaymentTokenResponse.class);
} catch (RestClientException exp) {
//TO-DO return error code
}
return null;
}
}

Spring Test + Mockito.mock - Spring fails because it tries to load the mocked bean #Autowired dependencies

I can't find out why the following simple scenario is failing: I have a Spring application with a filter that loads a Spring bean from the application context:
public class MyFilter implements Filter{
private IPermissionService permissionService;
public void init(FilterConfig filterConfig) throws ServletException {
WebApplicationContext ac = null;
try{
ac = WebApplicationContextUtils.getRequiredWebApplicationContext(filterConfig.getServletContext());
permissionService = ac.getBean(PermissionServiceImpl.class);
PermissionServiceImpl has an #Autowired attribute dataSource so in my TestNG test, I mock it in the Spring applicationContext:
#Configuration
public class MyFilterSpringTestConfig{
#Bean
public IPermissionService permissionService(){
return Mockito.mock(PermissionServiceImpl.class);
}
MyTest:
#Test
#WebAppConfiguration
#ContextConfiguration(classes=MyFilterSpringTestConfig.class)
public class MyFilterSpringTest extends BaseSpringFilterTest{
...
The problem is that on Spring initialization I get an exception complaining that PermissionServiceImpl's dataSource dependency is not satisfied. Since I wrapped it with a mock, why is it still failing? How could I fix it?
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [javax.sql.DataSource] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {#org.springframework.beans.factory.annotation.Autowired(required=true), #org.springframework.beans.factory.annotation.Qualifier(value=myDataSource)}
When mocking a class using Mockito (or any other mocking framework) that class is still an instance of the original class. With that comes that it also contains all the annotations and class information with it.
So when you create a mock of the class it still detects all annotations on it and tries to full fill that. I.e. #Autowire other instances.
Either don't use auto wiring or don't mock the class but the interface (which doesn't contain that information).

BeanCreationException on Spring TestNG PowerMock test

I'm getting BeanCreationException when using #AutoWired (Spring Annotation) and #PrepareForTest (PowerMock) and running my Spring enabled TestNG test.
I have a Spring controller, picked up via component scan.
I'm testing with TestNG, Mockito, and PowerMock.
I'm trying to spy on an auto wired controller thats autowired into the test, via: #AutoWired annotation.
Here's the beginning of the test class:
#PowerMockIgnore("*")
#WebAppConfiguration
#ContextConfiguration(locations = { "classpath:applicationContext-test.xml" })
#PrepareForTest(IWantAHamburgerController.class)
public class IWantAHamburgerControllerTest extends AbstractTestNGSpringContextTests {
#Autowired
private WebApplicationContext wac;
#Autowired
private MockHttpSession session;
#Autowired
private MockHttpServletRequest request;
#Autowired
private IWantAHamburgerController iWantAHamburgerController;
private MockMvc mockMvc;
#ObjectFactory
public IObjectFactory getObjectFactory() {
return new org.powermock.modules.testng.PowerMockObjectFactory();
}
#BeforeClass
public void setup() {
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
// see the note at the bottom of this post about this line
//iWantAHamburgerController = (IWantAHamburgerController) applicationContext.getBean("iWantAHamburgerController");
}
I'm trying to test a GET method on IWantAHamburgerController. This is what the test looks like:
#Test
public void testGetHamburgerAfterAskingThisQuestion() throws Exception {
Principal p = PowerMockito.mock(Principal.class);
PowerMockito.when(p.getName()).thenReturn("oneofthefiveguys");
IWantAHamburgerController spy = PowerMockito.spy(iWantAHamburgerController);
PowerMockito.doReturn("oneofthefiveguys").when(spy).getUserName("oneofthefiveguys");
mockMvc.perform(get("/hamburgers/everythinghamburger.html")).andExpect(status().isOk())
.andExpect(view().name("jsp/hamburger/everythinghamburger"))
.andExpect(forwardedUrl("jsp/hamburger/everythinghamburger"));
PowerMockito.verifyPrivate(spy).invoke("initGrill", "oneofthefiveguys");
new org.mockito.internal.debugging.MockitoDebuggerImpl().printInvocations(spy);
}
Inside the test I want to spy on the autowired iWantAHamburgerController in order to verify that initGrill was called by the GET method on the controller.
If I remove #PrepareForTest(IWantAHamburgerController.class) I do not get a BeanCreationException, but then PowerMock doesn't work.
Note: I've tried to manually set the iWantAHamburgerController bean, but when I do, I get a ClassCastException.
Here's the full stack:
org.springframework.beans.factory.BeanCreationException: Error
creating bean with name
'com.fiveguys.controllers.IWantAHamburgerControllerTest': Injection of
autowired dependencies failed; nested exception is
org.springframework.beans.factory.BeanCreationException: Could not
autowire field: private
com.fiveguys.controllers.IWantAHamburgerController
com.fiveguys.controllers.IWantAHamburgerControllerTest.iWantAHamburgerController;
nested exception is
org.springframework.beans.factory.NoSuchBeanDefinitionException: No
qualifying bean of type
[com.fiveguys.controllers.IWantAHamburgerController] found for
dependency: expected

Resources