我已经检查了很多SO评论以及Spring数据和单元测试的文档,但我无法让它工作,我不知道为什么它不起作用。
我有一个 junit 测试类,如下所示:
@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);
}
}
然后我的服务类看起来像这样
@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);
}
}
}
然后是我的存储库:
*/
public interface DealRepository extends CrudRepository<Deal, Long>{
public List<Deal> getDealsBy_country(String country);
public List<Deal> getAllDealsBy_employeeId(Long id);
}
我的配置文件如下所示:
@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;
}
}
但我收到此错误。
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)}
任何关于如何使用 spring data、junit 以及我的服务和存储库成功进行单元测试的建议将不胜感激。谢谢!
最佳答案
对于要注入(inject)的存储库 bean,
您需要使用 spring-data 注释之一来启用存储库。因此,将
@Enable*Repositories
添加到您的配置类您还需要配置 dB 工厂和其他相关 bean。我正在使用 Mongo 并且配置了 mongoDbFactory bean
在大多数情况下,您的测试配置应该类似于您的主配置,除了不必要的 bean 被模拟实现替换
更新 这是我的代码(抱歉我的代码在 mongo 中,我想你可以理解)
@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
}
}
这是我的测试配置文件...正如您所看到的,它明确排除了我的主配置文件。
@ContextConfiguration(classes = TestConfig)
@RunWith(SpringRunner.class)
class OrganizationServiceTest {
@Autowired
OrganizationService organizationService
@Test
void testRegister() {
def org = new Organization()
//...
organizationService.register(org)
// ...
}
那是我的测试课。它指的是测试配置,我建议使用命名配置类。您可以将常见选项放入父类(super class)中并扩展它们并将它们用于您的测试。
希望这有帮助
关于java - 如何使用服务和存储库为 Spring Data 设置单元测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41304135/