通过字段表示的不满足依赖关系-Springboot应用程序、组件和测试类都在同一个包中



我的理解是SpringBootApplication注释包括组件扫描

https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-using-springbootapplication-annotation.html

bean是在Application.main((中发现并打印的,为什么单元测试没有找到它?

此单元测试失败:

org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为"com.pds.pdssr.etlfile.EtlFileServicesTest"的bean时出错:通过字段"etlFileServices"表示的不满足依赖关系;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的"com.pds.pdssr.etlfile.EtlFileServices"类型的合格bean:应至少有1个符合自动连线候选条件的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true(}

通过适当的调试级别,即"org.springframework.context.annotation"="debug",我可以看到bean是在组件扫描过程中发现的。

尽管如此,单元测试结果为:

[错误]getAll(com.pds.pdssr.etlfile.EtlFileServicesTest(经过的时间:0.007 s<lt<错误!org.springframework.beans.factory.UnsatisfiedDependencyException:创建名为"com.pds.pdssr.etlfile.EtlFileServicesTest"的bean时出错:通过字段"etlFileServices"表示的不满足依赖关系;嵌套异常为org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的"com.pds.pdssr.etlfile.EtlFileServices"类型的合格bean:应至少有1个符合自动连线候选条件的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true(}由以下原因引起:org.springframework.beans.factory.NoSuchBeanDefinitionException:没有可用的"com.pds.pdssr.etlfile.EtlFileServices"类型的合格bean:应至少有1个符合自动连线候选条件的bean。依赖项注释:{@org.springframework.beans.factory.annotation.Autowired(required=true(}

应用:

package com.pds.pdssr.bootstrap;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;
//@EnableJpaRepositories("com.pds.pdsssr.jpa")
@SpringBootApplication
// @EntityScan("com.pds.pdssr.models")
public class Application {
private static final Logger logger = LoggerFactory.getLogger(Application.class);
public static void main(String[] args) {
ApplicationContext applicationContext = SpringApplication.run(Application.class, args);
for (String name : applicationContext.getBeanDefinitionNames()) {
logger.info("bean: " + name);
}
}
}

组件:

包com.pds.pssr.bootstrap;

import java.util.List;
import javax.persistence.EntityManagerFactory;
import javax.transaction.Transactional;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import com.pds.pdssr.models.EtlFile;
@Repository
public class EtlFileServices {
@Autowired
private static EntityManagerFactory entityManagerFactory;
public SessionFactory getSessionFactory() {
SessionFactory sessionFactory = null;
if (entityManagerFactory == null) {
throw new IllegalStateException("entityManagerFactory is null");
}
sessionFactory = entityManagerFactory.unwrap(SessionFactory.class);
if (sessionFactory == null) {
throw new NullPointerException("factory is not a hibernate factory");
}
return sessionFactory;
}

@SuppressWarnings("unchecked")
public List<EtlFile> getAll() {
return getAll("etlFile",getSessionFactory().getCurrentSession());
}
@SuppressWarnings("rawtypes")
protected List getAll(String tableName, Session session) {
String queryText = "from " + tableName;
return getList(tableName, queryText, session);
}

@SuppressWarnings("rawtypes")
protected List getList(String tableName, String queryText, Session session) {
long start = System.nanoTime();
Query query = session.createQuery(queryText);
List result = query.list();
long end = System.nanoTime();
long millis = (end - start) / 1000000;
//logger.debug("table: " + tableName + " millis " + millis + " rows:  " + result.size());
return result;
}

}

测试类别:

import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit4.SpringRunner;
import com.pds.pdssr.bootstrap.EtlFileServices;
import com.pds.pdssr.models.EtlFile;
@RunWith(SpringRunner.class)
public class EtlFileServicesTest {
@Autowired
private EtlFileServices etlFileServices;
@Test 
public void getAll() {
List<EtlFile>  etlFiles = etlFileServices.getAll();
assertNotNull(etlFiles);
}
}

原始答案:

你需要

@RunWith(SpringRunner.class)
@SpringBootTest(classes = YourMainClass.class)

在你的测试课上。

基于评论的进一步回答

如果你真的想在你的项目中有SessionFactory,你需要告诉spring框架显式地有SessionContext。可以通过添加来完成

spring.jpa.properties.hibernate.current_session_context_class = org.springframework.orm.hibernate5.SpringSessionContext

到您的配置文件。这是你的问题的一个工作例子。

HTH-

最新更新