Unit testing ONE piece of JSR 303 validator class in Spring - java

I would like to unit test one validator class in Spring. There are 6 other existing validator classes but they don't have unit tests so I only want to test my validator class.
My problem is that when I run my unit test (which tests only my class) "somehow" an other validator class is being tested... (it doesn't have unit test).
Is it possible that this is the default behaviour of the LocalValidatorFactoryBean to scan all the validator classes and to run their isValid method?
Can I specify the validator classes somehow that have to be tested? Like defining a ConstraintValidatorFactory?
Java test class
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(locations = {"/applicationContext-test-validator.xml"})
public class MyValidatorTest {
#Autowired
private Validator validator;
#Test
public void testIsValid_true() {
...
Set<ConstraintViolation<Record>> violations = validator.validate(data);
...
}
}
application context XML
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd">
<bean id="validator" class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />
</beans>
Thanks,
V.

Related

Define in Spring Boot Configuration Bean from groovy file

I want to know if it is possible in Spring Boot 2.x to define a class annotated with #Configuration in a groovy file and load the class as a normal annotated java class.
What I've done is define a class inside a groovy file annotated and then load it using xml bean definition of Spring, but it doesn't work.
SpringBoot main class annotated with #ImportResource("classpath:beans.xml")
xml file (beans.xml)
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:lang="http://www.springframework.org/schema/lang"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/lang http://www.springframework.org/schema/lang/spring-lang.xsd">
<lang:groovy id="jpaconfig" script-source="classpath:JpaConfig.groovy">
</lang:groovy>
</beans>
The groovy file
#Configuration
public class JpaConfig {
#Bean
#Primary
#ConfigurationProperties("spring.datasource")
public DataSourceProperties primaryDataSourceProperties() {
return new DataSourceProperties();
}
#Bean(name = "primaryDataSource")
#Primary
#ConfigurationProperties("spring.datasource.hikari")
public DataSource primaryDataSource() {
return primaryDataSourceProperties().initializeDataSourceBuilder().build();
}
}

Spring Autowiring not working on a field that belongs to a class in an external JAR

I am new to Spring as I inherited an existing project at work that was developed by another company using Spring 3.2.18, and I have come across the following problem:
I am working on application A (app A does not run on a web server), which uses as a dependency project B. I have the source code of B so I build it and include the jars as a maven dependency. Project B contains Class_1, Interface_2 and Class_2 (which implements Interface_2). Class_1 is in org.foo while Interface_2 and Class_2 is in org.toot.
In application A I need to Autowire Class_1 in a TestClass like this:
TestClass.java
#ContextConfiguration(locations={"file:src/test/spring/app-beans.xml"})
public class TestClass{
#Autowired
Class_1 class1;
// do stuff
}
app-beans.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.5.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">
<context:spring-configured />
<context:annotation-config />
<aop:aspectj-autoproxy />
<context:component-scan base-package="org.foo" />
<context:component-scan base-package="org.toot" />
<bean id="class_1" primary="true" class="org.foo.Class_1"/>
</beans>
Now the thing is that Class_1 in project B also has an autowired field:
Class_1.java
#Service
public class Class_1 {
#Autowired
Interface_2 int2;
}
Interface_2.java
public interface Interface_1 {
// stuff
}
Class_2.java
#Service
public class Class_2 implements Interface_2{
// stuff
}
Whenever I try to run my TestClass I get the following error:
Could not autowire field: private org.foo.Class_1;
nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException:
No qualifying bean of type [org.toot.Interface_1]
found for dependency [...]: expected at least 1 bean which qualifies as autowire candidate for this dependency.
What I get from it is that it somehow tries to autowire Class_1 but cannot autowire Interface_2 so it fails. How can I get the implementation of Interface_2 (Class_2) autowired to the field of Class_1? Project B does not have any spring-context files. Can I modify my app-beans.xml in project A to achieve it? Would I have to include context files in project B and re-build? Please share your knowledge and thank you for reading.

Spring doesn't instantiate bean at start

I'm stuck with the following problem. My application doesn't create my Services at startup and I end up with a NullPointerException when I try to use them in my Maven Tests after Inject them with #Autowired.
I don't understand where it comes from. I have done some research but I still don't understand why it doesn't work.
Here is the class where my Autowired administrationActionService is null:
public class AdministrationActionTests extends EntityTests {
#Autowired
AdministrationActionService administrationActionService;
#Test
public void equalsTests() {
administrationActionService.getExample();
[...]
The class :
package com.bloombooking.services;
#org.springframework.stereotype.Service
public class AdministrationActionService extends ServiceEntity{
#Autowired private AdministrationActionDao administrationActionDao;
[...]
And my ApplicationContext.xml. I've placed it in src/ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<context:component-scan base-package="com.bloombooking.services, com.bloombooking.dao"/>
</beans>
I really don't know what I could have done wrong. Can someone help me? Thanks!
To make it work you have to make the following changes:
add #RunWith(SpringJUnit4ClassRunner.class) to your class.
add #ContextConfiguration("path_to_you_spring_beans.xml")
So your class becomes:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration("path_to_you_spring_beans.xml")
AdministrationActionTests {
}

Spring: define custom #Transactional behavior in Java config

I would like Spring to rollback a transaction on methods annotated with #Transactional in case the method throws a checked exception. An equivalent of this:
#Transactional(rollbackFor=MyCheckedException.class)
public void method() throws MyCheckedException {
}
But I need this behavior to be default for all #Transactional annotations without the need to write it everywhere. We are using Java to configure Spring (configuration classes).
I tried the configuration suggested by spring documentation, which is only available in XML. So I tried to create this XML file:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="*" rollback-for="com.example.MyCheckedException" />
</tx:attributes>
</tx:advice>
</beans>
... and import it via #ImportResource. Spring did recognize and parse the file (I had some errors in it at first), but it doesn't work. The behavior of #Transactional has not changed.
I also tried defining my own transaction property source, as suggested in this answer. But it also used the XML configuration so I had to transform it into Java like this:
#Bean
public AnnotationTransactionAttributeSource getTransactionAttributeSource() {
return new RollbackForAllAnnotationTransactionAttributeSource();
}
#Bean
public TransactionInterceptor getTransactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
TransactionInterceptor transactionInterceptor = new TransactionInterceptor();
transactionInterceptor.setTransactionAttributeSource(transactionAttributeSource);
return transactionInterceptor;
}
#Bean
public BeanFactoryTransactionAttributeSourceAdvisor getBeanFactoryTransactionAttributeSourceAdvisor(TransactionAttributeSource transactionAttributeSource) {
BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
advisor.setTransactionAttributeSource(transactionAttributeSource);
return advisor;
}
This also didn't work - Spring kept using its own transaction property source (different instance than the one which was created in the configuration).
What is the correct way to achieve this in Java?
You should rather implement own annotation - reference
#Target({ElementType.METHOD, ElementType.TYPE})
#Retention(RetentionPolicy.RUNTIME)
#Transactional(rollbackFor=MyCheckedException.class)
public #interface TransactionalWithRollback {
}

logging with AOP in spring?

I am new to spring in my office . So there is no guidance for me.
I need to implement the logging with the AOP using the log4j.
I have implemented the logging without AOP in basic spring MVC example ?
Also did the small sample in AOP using the aspectJ without logging (just made the Sysout) ?
I don't know how to integrate it ?
Can any one please give me a start up idea?
Good answers are definitely appreciated ...
Spring makes it really easy for us to make use of AOP. Here's a simple logging example:
#Aspect
public class MyLogger {
private Logger log = Logger.getLogger(getClass());
#After("execution(* com.example.web.HomeController.*(..))")
public void log(JoinPoint point) {
log.info(point.getSignature().getName() + " called...");
}
}
Then simply configure your applicationContext.xml (or equivalent):
<aop:aspectj-autoproxy>
<aop:include name="myLogger"/>
</aop:aspectj-autoproxy>
<bean id="myLogger" class="com.example.aspect.MyLogger"/>
You'll notice in the MyLogger class that I specified #After right above the method. This is called the advice and it basically specifies that this 'log' method will be called after the method in question. Other options include #Before, #Around, #AfterThrowing.
The expression "execution(* com.example.web.HomeController.*(..))" is called a pointcut expression and specifies what we're targeting (in this case all methods of the HomeController class).
P.S. The aop namespace (xmlns:aop="http://www.springframework.org/schema/aop") and the schema location (version dependent) would need to be added to your applicationContext.xml right at the top. Here is my setup:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
You need to perform several steps to integrate Aspectj:
Install AspectJ
Add your aop.xml to META-INF\aop.xml in your project
Add aspectjrt-x.x.0.jar and aspectjweaver-x.x.0.jar in your project classpath
Add -javaagent:/path to aspectj installation/aspectjweaver-1.7.0.jar to your server's JVM.
Here is a sample aop.xml:
<aspectj>
<aspects>
<aspect name="test.MySimpleLoggerAspect" />
</aspects>
<weaver>
<include within="test.myproject.*" />
</weaver>
</aspectj>
If you are already using Spring then it is better to use Spring to simplify your setup.

Categories