4

私の春のアプリケーションのためにJUnitテストを書いています。私はこれが初めてなので、動作することがわかっているDAOクラスの単体テストを作成することから始めてみました(JBossで実行しました)。ただし、Eclipseでユニットテストとして機能させることはできません。「Beanの作成中にエラーが発生しました...フィールドを自動配線できませんでした:NoSuchBeanDefinition 」が表示され続けます

StackOverflowや他のサイトでこれに似たエラーが発生しましたが、常に構文エラーであるか、インターフェイスではなくインターフェイスの実装を自動配線しようとしました。コードにこれらのエラーは表示されません。

プロジェクトに付属のSpring構成とは別にSpring-test.jarをダウンロードしました。どちらもSpring2.5のものなので、問題になるとは思いません:/

EclipseにはJUnit4.8がバンドルされていますが、Spring Unit Testはそれで動作しないため、JUnitを4.4を使用するようにダウングレードしました。

考慮すべきことが1つあります...単体テストのコードを見ると、2つのフィールドが自動配線されていることがわかります。テストしたいクエリサービスのSimpleJdbcTemplateです。さて、DrugDaoとそれへのすべての参照を削除すると、SimpleJdbcQueryは問題なく自動配線されます。

レビューのスタックトレースは次のとおりです。

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tst.hcps.glucosemanagement.dataaccess.DrugDaoTest': Autowiring of fields failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.hcps.glucosemanagement.repository.meds.DrugDao tst.hcps.glucosemanagement.dataaccess.DrugDaoTest.dQuery; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.hcps.glucosemanagement.repository.meds.DrugDao] is defined: Unsatisfied dependency of type [interface com.hcps.glucosemanagement.repository.meds.DrugDao]: expected at least 1 matching bean
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:243)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:959)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:329)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:127)
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:85)
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:231)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:95)
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.invokeTestMethod(SpringJUnit4ClassRunner.java:139)
    at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
    at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
    at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
    at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
    at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: com.hcps.glucosemanagement.repository.meds.DrugDao tst.hcps.glucosemanagement.dataaccess.DrugDaoTest.dQuery; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.hcps.glucosemanagement.repository.meds.DrugDao] is defined: Unsatisfied dependency of type [interface com.hcps.glucosemanagement.repository.meds.DrugDao]: expected at least 1 matching bean
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:435)
    at org.springframework.beans.factory.annotation.InjectionMetadata.injectFields(InjectionMetadata.java:105)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessAfterInstantiation(AutowiredAnnotationBeanPostProcessor.java:240)
    ... 18 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.hcps.glucosemanagement.repository.meds.DrugDao] is defined: Unsatisfied dependency of type [interface com.hcps.glucosemanagement.repository.meds.DrugDao]: expected at least 1 matching bean
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:613)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:412)
    ... 20 more

インターフェースと実装は次のとおりです。

DrugDao.java

package com.hcps.glucosemanagement.repository.meds;

import java.util.List;

import com.hcps.glucosemanagement.domain.meds.Drug;

public interface DrugDao {

    public List<Drug> searchDrugsByPrimaryName(String facilityId, String name);

    public List<Drug> searchDrugs(String facilityId, String primaryName, String secondaryName);

}

SpringJdbcDrugQuery.java

package com.hcps.glucosemanagement.repository.meds;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.List;

import org.apache.log4j.Logger;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.simple.ParameterizedRowMapper;
import org.springframework.stereotype.Service;

import com.hcps.glucosemanagement.domain.meds.Drug;
import com.hcps.glucosemanagement.repository.DaoOperations;

@Service
public class SpringJdbcDrugQuery extends DaoOperations implements DrugDao {

private static final Logger logger = Logger.getLogger(SpringJdbcDrugQuery.class);

public List<Drug> searchDrugsByPrimaryName(String facilityId, String name) 
{
    return searchDrugs(facilityId, name, null);
}

public List<Drug> searchDrugs(String facilityId, String primaryName, String secondaryName) 
{
    List<Drug> results = null;

    StringBuffer sql = new StringBuffer();    
    HashMap<String, Object> namedParameters = new HashMap<String, Object>();

    if(primaryName==null) return null;

    sql = new StringBuffer();

    sql.append("SELECT");
            ...
        results = simpleJdbcTemplate.query(sql.toString(), new DrugMapper(), 


    return results;
}

private static final class DrugMapper implements ParameterizedRowMapper<Drug> 
{

    public Drug mapRow(ResultSet rs, int rowNum) throws SQLException {
        Drug drug = new Drug();
        drug.setFacilityId(rs.getString("FACILITY_ID"));
        drug.setPrimaryName(rs.getString("PRIMARY_NAME"));
        drug.setSecondaryName(rs.getString("SEC_NAME"));
        return drug;
    }

}
}

DrugDaoTest2.java(最初は別のソースフォルダーにあり、次に同じフォルダーで試しました)

package com.hcps.glucosemanagement.repository.meds;

import static org.junit.Assert.assertTrue;

import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.hcps.glucosemanagement.domain.meds.Drug;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={
        "classpath:common-test.xml"
})
public class DrugDaoTest2 {

    @Autowired
    DrugDao dQuery;
    @Autowired
    SimpleJdbcTemplate queryTemplate;

    @Test public void glucoseFetch() {
        List<Drug> rslts = dQuery.searchDrugsByPrimaryName(null, "INSU*");
        assertTrue(rslts.size()>0);
        int i=0;
        System.out.println(i);

    }

    public void setDrugDao(DrugDao drugDao) {
        this.dQuery = drugDao;
    }
}

common-test.xml

<?xml version="1.0" encoding="UTF-8" ?>

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:p="http://www.springframework.org/schema/p"
  xsi:schemaLocation="http://www.springframework.org/schema/beans
  http://www.springframework.org/schema/beans/spring-beans-2.5.xsd"
>

   <!--
   Test configuration for Spring/JUnit Testing
   -->

  <bean id="contextApplicationContextProvider" class="com.hcps.glucosemanagement.spring.ApplicationContextProvider" />

  <bean id="jmxExporter" class="org.springframework.jmx.export.MBeanExporter" lazy-init="false">
    <property name="beans">
      <map>
        <entry key="bean:name=Log4jJmxServiceMBean" value-ref="glucosemanagement.Log4jJmxService" />
      </map>
    </property>
  </bean>
  <bean id="glucosemanagement.Log4jJmxService" class="com.hcps.glucosemanagement.logging.Log4jJmxService" />

  <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
    <property name="basename" value="/WEB-INF/messages" />
  </bean>

  <bean id="parameterMappingInterceptor" class="org.springframework.web.portlet.handler.ParameterMappingInterceptor" />
  <bean id="viewResolverCommon" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
    p:order="2"
    p:cache="false"
    p:viewClass="org.springframework.web.servlet.view.JstlView"
    p:prefix="/WEB-INF/jsp/"
    p:suffix=".jsp"
  />

  <bean id="defaultExceptionHandler" class="org.springframework.web.portlet.handler.SimpleMappingExceptionResolver">
    <property name="defaultErrorView" value="../error"/>
    <property name="exceptionMappings">
      <props>
        <prop key="javax.portlet.PortletSecurityException">notAuthorized</prop>
        <prop key="javax.portlet.UnavailableException">notAvailable</prop>
      </props>
    </property>
  </bean>

  <bean id="simpleParameterJdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
    <constructor-arg ref="hciDataSource" />
  </bean>

  <bean id="hciDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url" value="jdbc:oracle:thin:@//vir-tst.com:1521/qar01.world" />
    <property name="username" value="ccuser" />
    <property name="password" value="bueno" />
    <property name="maxActive" value="30" />
    <property name="maxWait" value="30" />
    <property name="maxIdle" value="30" />
  </bean>

</beans>
4

4 に答える 4

4

私の間違い:私が見逃した別のSpring構成ファイルが他の場所で参照されていました。このフィールドを追加し、自動配線されたフィールドの単体テストでセッターを定義すると、問題が解決しました。

これらのタイプのエラーが発生した場合、現在このチェックリストを使用しています。

  • インターフェイスタイプの実装クラスが「@Service」アノテーションを使用していることを確認してください
  • BeanがXMLで正しく構成されていることを確認してください。
  • 最も簡単な方法は、次を使用することです。

<context:component-scan base-package="com.customization.packagename" />

  • これにより、パッケージ名ですべてのクラスが追加されます
  • または、XMLBean定義を作成します
于 2012-05-16T17:20:36.437 に答える
1

同様の問題があり、EclipseでAutoWireクラスを正常に実行できましたが、surefireではインターフェイスのみをAutoWiredにする必要があることがわかりました。特にこれは、インストルメンテーションにCoberturaを使用している場合にのみ発生するため、プロキシの生成に問題があることを確認してください。今のところ、ユースケースに適した新しいインターフェイスを導入したばかりですが、別の適切なソリューションがあるはずです。

于 2013-07-12T11:32:06.953 に答える
0

タイプのBean定義SpringJdbcDrugQueryをcommon-test.xmlに追加します

于 2012-05-15T22:29:46.100 に答える
-1

私もこの問題に遭遇し、セッターを追加するだけでうまくいきます。

于 2012-08-17T03:09:21.247 に答える