Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to autowire Service with-in JUnit Tests

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);
    }



}
like image 251
Ahmed Al-battashi Avatar asked Dec 20 '14 11:12

Ahmed Al-battashi


People also ask

Can we Autowire service in repository?

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.

Can we use Autowire in Test class?

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.

What is difference between @bean and @autowire?

@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).

Is @component required for Autowired?

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 .


1 Answers

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.

like image 136
Eugen Avatar answered Oct 19 '22 13:10

Eugen