我已经检查了许多SO评论以及弹簧数据和单元测试的文档,但我无法使其工作,我不知道为什么它不起作用。
我有一个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:无法加载ApplicationContext ...
引起: org.springframework.beans.factory.NoSuchBeanDefinitionException:没有 发现依赖的限定bean [com.globati.repository.DealRepository]:预计至少有1个bean 有资格成为autowire候选人。依赖注释: {@ org.springframework.beans.factory.annotation.Autowired(所需=真)}
有关如何使用spring数据,junit以及我的服务和存储库成功进行单元测试的任何建议将不胜感激。谢谢!
答案 0 :(得分:1)
要注入的存储库bean,
您需要使用其中一个弹簧数据注释启用存储库。因此,将@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)
// ...
}
这是我的测试课。它指的是测试配置,我建议使用命名配置类。您可以将常用选项放在超类上并扩展它们并将它们用于测试。
我希望这会有所帮助
答案 1 :(得分:0)
您可以尝试添加
@ActiveProfiles("your spring profile")
此外,我建议使用嵌入式测试数据库,如flapdoodle(https://github.com/flapdoodle-oss/de.flapdoodle.embed.mongo)
答案 2 :(得分:0)
你可以: