I have checked many SO comments and the docs for spring data and unit testing but I cant get this to work and I dont know why its not working.
I have a junit test class that looks like this:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(loader = AnnotationConfigContextLoader.class)
public class DealServiceTest {
@Configuration
static class ContextConfiguration {
// this bean will be injected into the OrderServiceTest class
@Bean
public DealService orderService() {
DealService dealService = new DealService();
// set properties, etc.
return dealService;
}
@Bean
public EmployeeService employeeService(){
EmployeeService employeeService = new EmployeeService();
return employeeService;
}
}
@Autowired
DealService dealService;
@Autowired
EmployeeService employeeService;
@Test
public void createDeal() throws ServiceException {
Employee employee = new Employee("Daniel", "tuttle", "danielptm@me.com", "dannyboy", "secret password", 23.234, 23.23);
Deal d = dealService.createDeal("ADSF/ADSF/cat.jpg", "A title goes here", "A deal description", 23.22, "Name of business", 23.23,23.23, employee, "USA" );
Assert.assertNotNull(d);
}
}
And then I have my service class that looks like this
@Service
public class DealService {
@Autowired
private DealRepository dealRepository;
public Deal createDeal(String image, String title, String description, double distance, String location, double targetLat, double targetLong, Employee employee, String country) throws ServiceException {
Deal deal = new Deal(image, title, description, distance, location, targetLat, targetLong, employee, country);
try {
return dealRepository.save(deal);
}catch(Exception e){
throw new ServiceException("Could not create a deal: "+deal.toString(), e);
}
}
public Deal updateDeal(Deal d) throws ServiceException {
try{
return dealRepository.save(d);
}catch(Exception e){
throw new ServiceException("Could not update deal at this time: "+d.toString(),e);
}
}
public List<Deal> getAllDealsForEmployeeId(Employee employee) throws ServiceException {
try{
return dealRepository.getAllDealsBy_employeeId(employee.getId());
}catch(Exception e){
throw new ServiceException("Could not get deals for employee: "+employee.getId(), e);
}
}
}
And then my repository:
*/
public interface DealRepository extends CrudRepository<Deal, Long>{
public List<Deal> getDealsBy_country(String country);
public List<Deal> getAllDealsBy_employeeId(Long id);
}
My config file looks like this:
@Configuration
@EnableJpaRepositories("com.globati.repository")
@EnableTransactionManagement
public class InfrastructureConfig {
@Bean
public DataSource dataSource() {
HikariConfig config = new HikariConfig();
config.setDriverClassName("com.mysql.jdbc.Driver");
config.setJdbcUrl("jdbc:mysql://localhost:3306/DatabaseProject");
config.setUsername("awesome");
config.setPassword("database");
return new HikariDataSource(config);
}
// @Bean
// public DataSource derbyDataSource(){
// HikariConfig config = new HikariConfig();
// config.setDriverClassName("jdbc:derby:memory:dataSource");
// config.setJdbcUrl("jdbc:derby://localhost:1527/myDB;create=true");
// config.setUsername("awesome");
// config.setPassword("database");
//
// return new HikariDataSource(config);
//
// }
@Bean
public JpaTransactionManager transactionManager(EntityManagerFactory factory) {
return new JpaTransactionManager(factory);
}
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
adapter.setDatabase(Database.MYSQL);
adapter.setGenerateDdl(true);
return adapter;
}
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
factory.setDataSource(dataSource()); //Get data source config here!
factory.setJpaVendorAdapter(jpaVendorAdapter());
factory.setPackagesToScan("com.globati.model");
return factory;
}
}
But I get this error.
java.lang.IllegalStateException: Failed to load ApplicationContext ...
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean found for dependency [com.globati.repository.DealRepository]: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
Any suggestions for how I can successfully do unit testing with spring data, junit and with my service and repositories would be greatly appreciated. Thanks!
For a repository bean to be injected,
You need to enable Repositories, using one of the spring-data annotations. So add @Enable*Repositories
to your configuration class
You also need dB factories and other related beans configured. I am using Mongo and I have mongoDbFactory bean configured
And for the most part your test configuration should look like your main configuration except for unnecessary bean replaced by mock implementations
UPDATE Here is my code (sorry mine is in mongo, I think you can relate)
@Configuration
@WebAppConfiguration
@ComponentScan(basePackages = "com.amanu.csa",
excludeFilters = @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, value = WebConfig.class))
@EnableMongoRepositories(repositoryImplementationPostfix = "CustomImpl")
class TestConfig {
@Bean
Mongo mongo() throws Exception {
return new MongoClient("localhost")
}
@Bean
MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(mongo(), "csa_test")
}
@Bean
MongoTemplate mongoTemplate() throws Exception {
MongoTemplate template = new MongoTemplate(mongoDbFactory())
template.setWriteResultChecking(WriteResultChecking.EXCEPTION)
return template
}
}
That is my test config file... As you can see it explicitly excludes my main configuration file.
@ContextConfiguration(classes = TestConfig)
@RunWith(SpringRunner.class)
class OrganizationServiceTest {
@Autowired
OrganizationService organizationService
@Test
void testRegister() {
def org = new Organization()
//...
organizationService.register(org)
// ...
}
And that is my test class. It refers to the test config, and I recommend using named config classes. You can put common options onto a super class and extend those and use them for your tests.
I hope this helps
You can try to add
@ActiveProfiles("your spring profile")
In addition I would suggest to use an embedded test db like flapdoodle ( https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo )
You could either :
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.