Junit , Mockito Integration with Vertx - vert.x

I am new vertx wanted to know which is the best junit framework and references that we should went through.
I tried using couple of things with mockito but services are not getting injected.
Please help in this.
UPDATE:
My TestClass looks something like this
public class GroupModeTest {
private static final Logger logger = LoggerFactory.getLogger(GroupMode.class);
public static GroupModeService service;
public static GroupModeDao dao;
private GroupMode groupMode;
private static GroupModeDao daoMock;
#BeforeAll
static void setup() {
logger.info("Starting Unit Tests for GroupMode");
daoMock = mock(GroupModeDao.class);
dao = new GroupModeDao();
service = new GroupModeService(daoMock);
}
#BeforeEach
void init() {
logger.info("Mocking new GroupMode Entity");
this.groupMode = new GroupMode();
}
#Test
public void testFakeWithMockito() throws IOException {
IGroupModeDao iGroupModeDao = mock(IGroupModeDao.class);
GroupMode groupMode = new GroupMode();
groupMode.setId(1L);
groupMode.setModeType("unique");
groupMode.setCreatedBy(1);
groupMode.setCreatedOn(LocalDateTime.now());
groupMode.setUpdatedBy(1);
groupMode.setUpdatedOn(LocalDateTime.now());
Single<Long> expected=Single.just(1L);
when(iGroupModeDao.create(groupMode)).thenReturn(expected);
GroupModeService groupModeService = new GroupModeService(iGroupModeDao);
Single<Long> actual= groupModeService.rxCreate("unique",1);
assertEquals(expected, actual);
}
}

Related

Spring Contract does not reach method #Before on base class

I have a single spring contract test:
public class ContractVerifierTest extends BaseClassForIntegrationTests {
#Test
public void validate_shouldSayHello() throws Exception {
// given:
RequestSpecification request = given()
.header("Content-Type", "application/json");
// when:
Response response = given().spec(request)
.get("/sayhello/Eduardo");
// then:
assertThat(response.statusCode()).isEqualTo(200);
assertThat(response.header("Content-Type")).matches("application/json.*");
// and:
DocumentContext parsedJson = JsonPath.parse(response.getBody().asString());
assertThatJson(parsedJson).field("['msg']").isEqualTo("hello Eduardo");
}
}
My base class looks like:
#RunWith(SpringRunner.class)
#SpringBootTest(classes = DemoApplication.class, webEnvironment = WebEnvironment.DEFINED_PORT)
#Slf4j
public class BaseClassForIntegrationTests {
#Value("${app.url}") private String url;
#Value("${app.port}") private int port;
#Before
public void setup() {
log.error("Running setup with url:" + url + ":" + port);
RestAssured.baseURI = url;
RestAssured.port = port;
}
}
The setup method is never reached, funny thing, if I change the annotation to #BeforeEach or #BeforeAll it works as expected.
I have a sample of the project here
With Contract 3.0.x the default testing framework is junit5 you need to Configure the plugin explicitly to use junit 4

Integration Tests for RESTEasy Endpoint

I want to perform integration tests on my REST endpoint but am running into issues.
Below is my endpoint. NOTE: I cannot change this part of the code.
#Path("/people")
public class PersonResource {
private final PersonService personService;
#Inject
public PersonResource(final PersonService personService) {
this.personService = personService;
}
#GET
#Produces("application/json")
public List<Person> getPersonList() {
return personService.getPersonList();
}
}
From what I've been able to find online, I have the following basic structure for my test.
public class PersonResourceTest {
private Dispatcher dispatcher;
private POJOResourceFactory factory;
#Before
public void setup() {
dispatcher = MockDispatcherFactory.createDispatcher();
factory = new POJOResourceFactory(PersonResource.class);
dispatcher.getRegistry().addResourceFactory(factory);
}
#Test
public void testEndpoint() throws URISyntaxException {
MockHttpRequest request = MockHttpRequest.get("people");
MockHttpResponse response = new MockHttpResponse();
dispatcher.invoke(request, response);
System.out.print("\n\n\n\n\n" + response.getStatus() + "\n\n\n\n\n");
System.out.print("\n\n\n\n\n" + response.getContentAsString() + "\n\n\n\n\n");
}
}
However, this results in the following error on the last line of the setup method.
java.lang.RuntimeException: RESTEASY003190: Could not find constructor for class: my.path.PersonResource
I explored the Registry API and thought maybe I should have been using addSingletonResource instead, so I changed the last line of setup to dispatcher.getRegistry().addSingletonResource(personResource); and added the following.
#Inject
private PersonResource personResource;
But that results in a NullPointerException on the last line of setup.
The sparse documentation on the mocking isn't very helpful. Can anyone point out where I'm going wrong? Thanks.
You need to do two things
Add a no arguments constructor to your source class:
public PersonResource() {
this(null)
}
In the test class, initialize the PersonResource class with an instance of PersonService class:
dispatcher.getRegistry().addSingletonResource(new PersonResource(new PersonService()));
If needed, the PersonService class can be mocked:
private Dispatcher dispatcher;
#Mock
private PersonService service;
#Before
public void setup() {
MockitoAnnotations.initMocks(this);
dispatcher = MockDispatcherFactory.createDispatcher();
PersonResource resource= new PersonResource(service);
ispatcher.getRegistry().addSingletonResource(resource);
}
Hope it helps!

spring webclient unit test with mockito

I'm trying to write a test for my controller (which has an autowired field pageModelService)
here is my test class:
#RunWith(MockitoJUnitRunner.class)
public class PageModelControllerTest {
#Mock
private PageModelService pageModelService;
#InjectMocks
private PageModelController pageModelController;
private WebTestClient client;
#Before
public void setup() {
client = WebTestClient.bindToController(pageModelController).build();
}
}
I can't create the client, it tells me it can't autowire pageModelService
any idea

How to run update query in Spring JPA for quartz job

I have a quartz job in spring 4 and I am using JPA hibernate to update database value through quartz job but I am getting javax.persistence.TransactionRequiredException: Executing an update/delete query
I don't understand what kind of configuration is missing in quartz job. I referred to SpringBeanAutowiringSupport example still update is failing but select is working fine.
Below is my code
#Configuration
#ComponentScan("com.stock")
public class QuartzConfiguration {
#Autowired
private ApplicationContext applicationContext;
#Bean
public JobDetailFactoryBean jobDetailBalanceCarryForward(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(BillingCroneSvcImpl.class);
Map<String,Object> map = new HashMap<String,Object>();
map.put("task", "balanceCarryForward");
factory.setJobDataAsMap(map);
factory.setGroup("BalanceCarryForwardJob");
factory.setName("balance carry forward");
return factory;
}
#Bean
public CronTriggerFactoryBean cronTriggerBalanceCarryForward(){
CronTriggerFactoryBean stFactory = new CronTriggerFactoryBean();
stFactory.setJobDetail(jobDetailBalanceCarryForward().getObject());
stFactory.setStartDelay(3000);
stFactory.setName("balancCarryForwardTrigger");
stFactory.setGroup("balanceCarryForwardgroup");
stFactory.setCronExpression("0 0/1 * 1/1 * ? *");
return stFactory;
}
#Bean
public SpringBeanJobFactory springBeanJobFactory() {
AutoWiringSpringBeanJobFactory jobFactory = new AutoWiringSpringBeanJobFactory();
jobFactory.setApplicationContext(applicationContext);
return jobFactory;
}
#Bean
public SchedulerFactoryBean schedulerFactoryBean() {
SchedulerFactoryBean schedulerFactory = new SchedulerFactoryBean();
schedulerFactory.setJobFactory(springBeanJobFactory());
schedulerFactory.setTriggers(cronTriggerBalanceCarryForward().getObject());
return schedulerFactory;
}
}
Below class where quartz executeInternal method is written
#Service
#PersistJobDataAfterExecution
#DisallowConcurrentExecution
#Autowired
private BillingCroneRepo billingCroneRepo;
public class BillingCroneSvcImpl extends QuartzJobBean implements BillingCroneSvc {
#Override
#Transactional
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(context);
billingCroneRepo.updateBalance();
// this method throws exception javax.persistence.TransactionRequiredException: Executing an update/delete query
}
}
App config class
#EnableWebMvc
#EnableTransactionManagement
#Configuration
#ComponentScan({ "com.stock.*" })
#Import({ SecurityConfig.class })
#PropertySource("classpath:jdbc.properties")
public class AppConfig extends WebMvcConfigurerAdapter {
private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";
private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";
private static final String PROPERTY_NAME_DATABASE_URL = "db.url";
private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";
private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";
private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";
private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";
#Resource
private Environment env;
#Bean(name = "dataSource")
public DriverManagerDataSource dataSource() {
DriverManagerDataSource driverManagerDataSource = new DriverManagerDataSource();
driverManagerDataSource.setDriverClassName(env.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));
driverManagerDataSource.setUrl(env.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));
driverManagerDataSource.setUsername(env.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));
driverManagerDataSource.setPassword(env.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));
return driverManagerDataSource;
}
#Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);
entityManagerFactoryBean.setPackagesToScan(env.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));
entityManagerFactoryBean.setJpaProperties(hibProperties());
return entityManagerFactoryBean;
}
private Properties hibProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL,env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
return properties;
}
#Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
return transactionManager;
}
#Bean
public ReloadableResourceBundleMessageSource messageSource(){
ReloadableResourceBundleMessageSource messageSource=new ReloadableResourceBundleMessageSource();
String[] resources= {"classpath:messages"};
messageSource.setBasenames(resources);
return messageSource;
}
#Bean
public LocaleResolver localeResolver() {
final CookieLocaleResolver ret = new CookieLocaleResolver();
ret.setDefaultLocale(new Locale("en_IN"));
return ret;
}
#Bean
public LocaleChangeInterceptor localeChangeInterceptor(){
LocaleChangeInterceptor localeChangeInterceptor=new LocaleChangeInterceptor();
localeChangeInterceptor.setParamName("language");
return localeChangeInterceptor;
}
#Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/Angular/**").addResourceLocations("/Angular/");
registry.addResourceHandler("/css/**").addResourceLocations("/css/");
registry.addResourceHandler("/email_templates/**").addResourceLocations("/email_templates/");
registry.addResourceHandler("/fonts/**").addResourceLocations("/fonts/");
registry.addResourceHandler("/img/**").addResourceLocations("/img/");
registry.addResourceHandler("/js/**").addResourceLocations("/js/");
registry.addResourceHandler("/Landing_page/**").addResourceLocations("/Landing_page/");
}
#Bean
public static PropertySourcesPlaceholderConfigurer properties() {
PropertySourcesPlaceholderConfigurer pspc = new PropertySourcesPlaceholderConfigurer();
org.springframework.core.io.Resource[] resources = new ClassPathResource[] { new ClassPathResource("application.properties") };
pspc.setLocations(resources);
pspc.setIgnoreUnresolvablePlaceholders(true);
return pspc;
}
#Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/pages/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
// through below code we directly read properties file in jsp file
#Bean(name = "propertyConfigurer")
public PropertiesFactoryBean mapper() {
PropertiesFactoryBean bean = new PropertiesFactoryBean();
bean.setLocation(new ClassPathResource("application.properties"));
return bean;
}
}
Can anybody please assist me how to resolve transational issue in spring JPA with quartz
Thanks you all for your help. Finally I autowired EntityManagerFactory instead of persitance EntityManager and it is working fine. I tried all scenario but nothing worked to inject spring transactional in quartz so finally autoriwed entitymanagerfactory
Below is my repo class code.
#Repository
public class BillingCroneRepoImpl implements BillingCroneRepo {
/*#PersistenceContext
private EntityManager entityManager;*/
#Autowired
EntityManagerFactory entityManagerFactory;
public boolean updateTable(){
EntityManager entityManager = entityManagerFactory.createEntityManager();
EntityTransaction entityTransaction = entityManager.getTransaction();
entityTransaction.begin(); // this will go in try catch
Query query = entityManager.createQuery(updateSql);
// update table code goes here
entityTransaction.commit(); // this will go in try catch
}
}
I'm not the Spring specialist, but I think new ... doesn't work with #Transactional
#Service
#PersistJobDataAfterExecution
#DisallowConcurrentExecution
public class BillingCroneSvcImpl extends QuartzJobBean implements BillingCroneSvc {
#Autowired
BillingCroneRepo billingCroneRepo;
#Override
#Transactional
protected void executeInternal(JobExecutionContext context) throws JobExecutionException {
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(context);
billingCroneRepo.updateBalance();
}
}
It's because quartz is using the bean instead of the proxy generated for #Transactional.
Use either MethodInvokingJobDetailFactoryBean (instead of inheriting QuartzJob) or use a dedicated wrapper quarz bean (inheriting from QuartzJob) that call the spring bean (not inheriting from QuartzJob) having the #Transactionnal annotation.
EDIT : this is in fact not the problem
The problem is here :
JobDetailFactoryBean factory = new JobDetailFactoryBean();
factory.setJobClass(BillingCroneSvcImpl.class);
By passing the class, I presume that Quartz will instantiate it itself, so Spring won't create it and won't wrap the bean in a Proxy that handle the #Transactionnal behaviour.
Instead you must use something along the line :
#Bean(name = "billingCroneSvc")
public BillingCroneSvc getSvc(){
return new BillingCroneSvcImpl();
}
#Bean
public JobDetailFactoryBean jobDetailBalanceCarryForward(){
JobDetailFactoryBean factory = new JobDetailFactoryBean();
getSvc();// just make sure the bean is instantiated
factory.setBeanName("billingCroneSvc");
...
}

When more than one tests added to rest controller test why am I getting WebApplicationContext is required?

This is very funny. When I ran my controller test with more than one tests I am getting the following error when i run it with maven, but works fine in eclipse Junit.java.lang.IllegalArgumentException: WebApplicationContext is required
at org.springframework.util.Assert.notNull(Assert.java:112)
at org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder.<init>(DefaultMockMvcBuilder.java:43)
at org.springframework.test.web.servlet.setup.MockMvcBuilders.webAppContextSetup(MockMvcBuilders.java:46)
at com.akrilist.rest.web.akripost.controller.AbstractRestControllerTest.setup(AbstractRestControllerTest.java:32)
at com.akrilist.rest.web.akripost.controller.AutoPostControllerTest.setup(AutoPostControllerTest.java:36) Then I ran one test commenting the other alternately (commented testA then run testB, then commented testB then run testA) both are passing. I have no idea what is happening when I put both of then are active tests. if any of you have clue please let me know. I have put my classes here.
AbstractRestControllerTest
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes = { TestRestServiceConfig.class, WebAppConfig.class })
#WebAppConfiguration
public abstract class AbstractRestControllerTest {
protected MockMvc mockMvc;
#Autowired
protected WebApplicationContext webApplicationContext;
/*#Inject
protected UserAccountService userAccountServiceMock;*/
#Before
public void setup() {
/* Mockito.reset(userAccountServiceMock);*/
mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
}
AutoPostControllerTest
public class AutoPostControllerTest extends AbstractRestControllerTest {
#Autowired
private AutoPostService autoPostServiceMock;
#Autowired
private AutoPostConverter autoPostConverterMock;
#Before
public void setup() {
// Mockito.reset(autoPostServiceMock);
// Mockito.reset(commentPostRepositoryMock);
super.setup();
}
#Test
public void testValidationErrorForNullProfileId() throws Exception {
String description = TestUtil.createStringWithLength(501);
AutoPost autoPost = new TestAutoPostBuilder().description(description).buildModel();
mockMvc.perform(post("/auto/post").contentType(TestUtil.APPLICATION_JSON_UTF8).content(TestUtil.convertObjectToJsonBytes(autoPost))).andExpect(status().isBadRequest())
.andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
// .andExpect(jsonPath("$[]", hasSize(1)))
.andExpect(jsonPath("$.type", is("validation failure")));
verifyZeroInteractions(autoPostServiceMock);
}
#Test
public void testGet_shouldReturnPost() throws Exception {
String description = TestUtil.createStringWithLength(501);
String postId = TestUtil.createStringWithLength(16);
Integer profileId = 123456;
TestAutoPostBuilder testAutoPostBuilder = new TestAutoPostBuilder();
AutoPost post = testAutoPostBuilder.postId(postId).description(description).profileId(profileId).buildModel();
when(autoPostServiceMock.get(postId)).thenReturn(post);
when(autoPostConverterMock.convertTo(post)).thenReturn(testAutoPostBuilder.buildDto());
mockMvc.perform(get("/auto/post/" + postId).contentType(TestUtil.APPLICATION_JSON_UTF8)).andExpect(status().isOk()).andExpect(content().contentType(TestUtil.APPLICATION_JSON_UTF8))
.andExpect(jsonPath("$.postId", is(postId))).andExpect(jsonPath("$.profileId", is(profileId))).andExpect(jsonPath("$.links", hasSize(1)));
verify(autoPostServiceMock, times(1)).get(anyString());
verifyNoMoreInteractions(autoPostServiceMock);
}
}
I fixed this issue. It was because of parallel configuration of maven-surefire-plugin. I changed its value to 'classes', so the issue is over. There are two ways we can fix this issue. One is
<parallel>classes</parallel>
<threadCount>10</threadCount>
other way annotating the test class with #net.jcip.annotations.NotThreadSafe that required sequential execution.