How to autowire Service in test class by only using spring-annotations
when I try I got this error below , whereas @Service annotation used in UserServiceImp class
2014-12-20 15:35:52 ERROR TestContextManager:334 - Caught exception while allowing TestExecutionListener [org.springframework.test.context.support.DependencyInjectionTestExecutionListener@5af97850] to prepare test instance [com.amsb.bariz.base.test.UserTest@4520ebad] org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.amsb.bariz.base.test.UserTest': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: public com.amsb.bariz.base.service.UserService com.amsb.bariz.base.test.UserTest.userService; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type [com.amsb.bariz.base.service.UserService] 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)}
my Service Class is
package com.amsb.bariz.base.service.imp;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;
import com.amsb.bariz.base.dao.UserDao;
import com.amsb.bariz.base.dao.UserRoleDao;
import com.amsb.bariz.base.entity.User;
import com.amsb.bariz.base.entity.UserRole;
import com.amsb.bariz.base.service.UserService;
@Service("userService")
public class UserServiceImp implements UserService {
@Autowired
private UserDao userDao;
@Autowired
private UserRoleDao userRoleDao;
public void register(User user) {
PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
user.setPassword(passwordEncoder.encode(user.getPassword()));
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
Date dateNow = new Date(20070266);
Timestamp dn = new Timestamp(now.getTime());
user.setStatus("P");
user.setCreated_on(dn);
user.setEnabled(false);
UserRole ur = new UserRole(user,"USER_ROLE");
System.out.println("XDXDX ::" + user.toString());
userDao.create(user);
userRoleDao.create(ur);
}
}
my Test Class is :
package com.amsb.bariz.base.test;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.junit.Test;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
import org.springframework.test.context.support.DirtiesContextTestExecutionListener;
import org.springframework.test.context.transaction.TransactionalTestExecutionListener;
import com.amsb.bariz.base.dao.UserDao;
import com.amsb.bariz.base.entity.User;
import com.amsb.bariz.base.entity.UserRole;
import com.amsb.bariz.base.service.UserService;
import com.github.springtestdbunit.DbUnitTestExecutionListener;
import junit.framework.TestCase;
import junit.framework.TestSuite;
@Configuration
@ComponentScan(basePackages={"com.amsb.bariz.base.service"})
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:spring/spring-main.xml"})
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class,
DirtiesContextTestExecutionListener.class,
TransactionalTestExecutionListener.class,
DbUnitTestExecutionListener.class})
public class UserTest {
@Autowired
public UserService userService;
@Test
public void userAdd() {
User user = new User();
Calendar calendar = Calendar.getInstance();
java.util.Date now = calendar.getTime();
Timestamp doo = new Timestamp(now.getTime());
Date a = new Date(0);
user.setPassword("oman");
user.setName("oman new ");
user.setStatus("N");
user.setCreated_on(doo);
user.setUpdated_on(doo);
user.setDob(new Date(20140522));
user.setUsername("[email protected]");
userService.register(user);
}
}
The autowiring of classes is done in order to access objects and methods of another class. But inside the service layer we always autowire the repository interface to do all the DML operations on the database.
To check the Service class, we need to have an instance of the Service class created and available as a @Bean so that we can @Autowire it in our test class. We can achieve this configuration using the @TestConfiguration annotation.
@Bean is just for the metadata definition to create the bean(equivalent to tag). @Autowired is to inject the dependancy into a bean(equivalent to ref XML tag/attribute).
So the answer is: No, @Autowired does not necessarily mean you must also use @Component . It may be registered with applicationContext. xml or @Configuration+@Bean .
Are you trying to use the test itself as a part of the Spring configuration? That's not going to work. What you need to do is:
- remove the @Configuration
and @ComponentScan
annotations from the test itself
- create a simple TestConfiguration
class:
@Configuration
@ComponentScan(basePackages={"com.amsb.bariz.base.service"})
@ImportResource("classpath:spring/spring-main.xml")
public class TestConfiguration{ }
And just reference that in your test:
@ContextConfiguration(classes = { TestConfiguration.class }, loader = AnnotationConfigContextLoader.class)
public class UserTest {
And you should be able to inject your service just fine.
Hope it helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With