如何解决弹簧自动接线不适用于正在测试的类
我正在尝试对正在编写的Web服务中使用的部分代码进行高级测试。在此过程中,预期代码将调用数据库(我已经使用Spring和Hibernate对其进行了设置)。自动装配在测试用例类本身中可以正常工作,但是由于运行测试而被调用的其他类没有被自动装配。 单元测试@RunWith( SpringJUnit4ClassRunner.class )
@ContextConfiguration
public class ProviderTest
{
@Autowired
protected ApplicationContext applicationContext;
protected ProviderA provider;
@Before
public void setUp()
{
Transaction transaction = DbLogHelper.getInstance().getLog();
transaction.setCompanyName(\"Unit Test\");
transaction.setCreateTime(Calendar.getInstance());
transaction.setPhoneNumber(\"Provider Test - N/A\");
transaction.setQueryId(\"Unit Test\");
transaction.setRequest(\"<NONE - UNIT TEST>\");
transaction.setResponse(\"<NONE - UNIT TEST>\");
LogJob job = new LogJob(transaction,DbLogHelper.getInstance.getDao());
job.run();
provider = new ProviderA(transaction);
}
@After
public void tearDown()
{
Transaction transaction = DbLogHelper.getInstance().getLog();
transaction.setResponseTime(Calendar.getInstance());
DbLogHelper.getInstance().writeLog(transaction);
DbLogHelper.getInstance().resetLog();
}
@Test
public void testProvider()
{
try
{
List<TAddress> results = provider.searchItem(\"SOME_ITEM\",\"12345\");
Assert.assertNotNull(results);
}
catch (Exception e)
{
Assert.fail();
}
}
}
单例日志助手
public class DbLogHelper
{
private static DbLogHelper instance;
@Autowired
private LogDao dao;
private Executor executor = new ThreadPoolExecutor(3,10,TimeUnit.SECONDS,new LinkedBlockingQueue<Runnable>());
private ThreadLocal<Transaction> transactionRef = new ThreadLocal<Transaction>() {
@Override
protected Transaction initialValue()
{
return new Transaction();
}
};
public static DbLogHelper getInstance()
{
if (instance == null)
{
synchronized (DbLogHelper.class)
{
if (instance == null)
{
instance = new DbLogHelper();
}
}
}
return instance;
}
/**
* Gets the Transaction object attached to this thread. Generates a new one if it does not
* yet exist.
* @return Transaction
*/
public Transaction getLog()
{
return transactionRef.get();
}
/**
* Removes the current Transaction object from the thread map. The next getLog() call will
* generate a new one.
*/
public void resetLog()
{
transactionRef.remove();
}
/**
* Gets the DAO used to persist Transaction objects
*/
public LogDao getDao()
{
return dao;
}
/**
* Queues the passed Transaction object to be written to the database. This happens in a
* separate thread so the service is not waiting on database persistence before responding.
* @param transaction
*/
public void writeLog(Transaction transaction)
{
LogJob job = new LogJob(transaction,dao);
executor.execute(job);
}
}
日志DAO
@Repository
public class LogDao
{
private static Logger log = LoggerFactory.getLogger(LogDao.class);
private EntityManager entityManager;
@PersistenceContext
public void setEntityManager(EntityManager entityManager) {
log.debug(\"Entity Manager set on LogDao\");
this.entityManager = entityManager;
}
@Transactional
public void updateTransaction(Transaction log)
{
log = entityManager.merge(log);
}
}
ProviderTest-context.xml
<!-- database -->
<bean id=\"datasource\" class=\"org.springframework.jdbc.datasource.DriverManagerDataSource\">
<property name=\"driverClassName\" value=\"com.MysqL.jdbc.Driver\" />
<!-- uncomment to see sql
<property name=\"driverClassName\" value=\"com.p6spy.engine.spy.P6SpyDriver\" />
-->
<property name=\"url\" value=\"jdbc:MysqL://localhost\" />
<property name=\"username\" value=\"root\" />
<property name=\"password\" value=\"\" />
</bean>
<!-- LOCAL entity manager factory -->
<bean id=\"entityManagerFactory\" class=\"org.springframework.orm.jpa.LocalContainerEntityManagerfactorybean\">
<!-- <property name=\"persistenceUnitManager\" ref=\"persistenceUnitManager\"/> -->
<property name=\"persistenceUnitName\" value=\"domainPersistenceUnit\" />
<property name=\"dataSource\" ref=\"datasource\" />
<property name=\"jpavendorAdapter\">
<bean class=\"org.springframework.orm.jpa.vendor.HibernateJpavendorAdapter\">
<property name=\"showsql\" value=\"false\" />
<!-- <property name=\"generateDdl\" value=\"true\" /> -->
<property name=\"databasePlatform\" value=\"org.hibernate.dialect.MysqLDialect\" />
</bean>
</property>
</bean>
<bean class=\"org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor\"/>
<bean class=\"org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor\" />
<bean id=\"transactionManager\" class=\"org.springframework.orm.jpa.JpaTransactionManager\">
<property name=\"entityManagerFactory\" ref=\"entityManagerFactory\" />
<property name=\"dataSource\" ref=\"datasource\" />
</bean>
<context:annotation-config/>
<context:component-scan base-package=\"com.company.application.webservice\"/>
DbLogHelper中的自动连线DAO总是以null结尾。但是,如果我直接在单元测试中对其进行自动布线,那么实体管理器就可以进行注入了。当然,我担心的是,如果它在测试中无法正常工作,则在正确部署时将无法正常工作。即使我不必为此担心,我仍然想对其进行测试。
解决方法
DBLogger不是Spring bean,因此spring无法将其自动连接到任何类(因为它不知道该类)。我建议在您的spring上下文中将其定义为bean,并将DbLogHelper注入到您要使用它的任何类中。
, 您应该将DBLogger定义为@John Vint提到的spring bean,或者如果由于某种原因而不能,则可以从spring应用程序上下文中获取要自动装配的对象(不推荐)。
有关后者的详细信息:
http://www.javacodegeeks.com/2015/03/using-spring-managed-bean-in-non-managed-object.html
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。