1

SpringMVCとJUnitは初めてです。基本的に私はサービスクラスを自動配線したいので、このクラスはSpringコンテキストでロードする必要があります。

サービス

    @サービス
    パブリッククラスFundService{
        @Autowired
        FundDAO FundDAO;

        / **
         * @戻る
         * /
        public List getFundDetails(String productId){

            FundDAO.getFundDetails(productId);を返します。
        }   
    }

アプリケーションコンテキスト

<beans>

    <mvc:annotation-driven />

    <context:component-scan base-package="com.test.*" />
</beans>

JUnitクラス

    @RunWith(SpringJUnit4ClassRunner.class)
    @ContextConfiguration(locations = {"classpath *:/ WEB-INF / application-context.xml"})
    パブリッククラスCompensationServiceTest{

        @Autowired
        プライベートFundServicefundService;

        @テスト
        public void verifyGetCompensationList()
        {{
            System.out.println(fundService == null);
        }
    }

テストの実行中に、次の例外トレースが表示されます

    org.springframework.beans.factory.BeanCreationException:「com.test.admin.service.CompensationServiceTest」という名前のBeanの作成中にエラーが発生しました:自動配線された依存関係の挿入に失敗しました。ネストされた例外はorg.springframework.beans.factory.BeanCreationExceptionです:フィールドを自動配線できませんでした:private com.test.admin.service.FundService com.test.admin.service.CompensationServiceTest.fundService; ネストされた例外はorg.springframework.beans.factory.NoSuchBeanDefinitionExceptionです:依存関係に一致するタイプ[com.test.admin.service.FundService]のBeanが見つかりません:この依存関係の自動配線候補として適格な少なくとも1つのBeanが必要です。依存関係のアノテーション:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
        org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:286)で
        org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1064)で
        org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.autowireBeanProperties(AbstractAutowireCapableBeanFactory.java:374)で
        org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:110)で
        org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:75)で
        org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:333)で
        org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:220)で
        org.springframework.test.context.junit4.SpringJUnit4ClassRunner $ 1.runReflectiveCall(SpringJUnit4ClassRunner.java:301)で
        org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)で
        org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:303)で
        org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:240)で
        org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)で
        org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:193)で
        org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:52)で
        org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)で
        org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:42)で
        org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:184)で
        org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)で
        org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)で
        org.junit.runners.ParentRunner.run(ParentRunner.java:236)で
        org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:180)で
        org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:49)で
        org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)で
        org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)で
        org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)で
        org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)で
        org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)で
    原因:org.springframework.beans.factory.BeanCreationException:フィールドを自動配線できませんでした:private com.test.admin.service.FundService com.test.admin.service.CompensationServiceTest.fundService; ネストされた例外はorg.springframework.beans.factory.NoSuchBeanDefinitionExceptionです:依存関係に一致するタイプ[com.test.admin.service.FundService]のBeanが見つかりません:この依存関係の自動配線候補として適格な少なくとも1つのBeanが必要です。依存関係のアノテーション:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
        org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:507)で
        org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:84)で
        org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:283)で
        ...26もっと
    原因:org.springframework.beans.factory.NoSuchBeanDefinitionException:依存関係に一致するタイプ[com.test.admin.service.FundService]のBeanが見つかりません:この依存関係のautowire候補として適格なBeanが少なくとも1つ必要です。依存関係のアノテーション:{@ org.springframework.beans.factory.annotation.Autowired(required = true)}
        org.springframework.beans.factory.support.DefaultListableBeanFactory.raiseNoSuchBeanDefinitionException(DefaultListableBeanFactory.java:903)で
        org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:772)で
        org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:686)で
        org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor $ AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)で
        ...28もっと

4

5 に答える 5

2

まず第一に、WEB-INFフォルダは決してクラスパスにあるべきではありません。プロジェクトのファイルシステムにあるはずです。したがって、Mavenプロジェクト構造を使用する場合、そのフォルダーはプロジェクトのルート(つまり、src/main/webapp/WEB-INF)を基準にして配置されます。その場合、そのフォルダー内のXML構成ファイルを次のようなファイルシステムリソースとして宣言する必要があります。

@ContextConfiguration("file:src/main/webapp/WEB-INF/application-context.xml")

次に、これがテスト構成ファイルである場合は、の下に保存しないでくださいWEB-INF。代わりに、クラスパスに保存する必要があります。Mavenプロジェクト構造に従うと、これはsrc/test/resources/application-context.xml次のようになります。この場合、テストで次の宣言を使用します。

@ContextConfiguration("/application-context.xml")

また

@ContextConfiguration("classpath:application-context.xml")

...どちらでもお好みですが、同等であることに注意してください。

よろしくお願いいたします。

サム

于 2012-08-20T12:28:45.450 に答える
2

2つのオプションがあります。

これを使用@Autowireする場合は、テスト用のアプリケーションコンテキストを作成していることを意味します。これを実現するには、いくつかの手順があります。方法を説明するのではなく、正しいアプローチについて説明したいと思います。

単体テストについて話しているので、テストしているクラスが分離されており、注入された依存関係はモックでなければならないことを意味します。次の例:

クラス:

@RestController
@RequestMapping(value = "/")
public class CatalogRest {

    @Autowired
    private CatalogService catalogService;

    @Autowired
    private LoggedUser loggedUser;

    @RequestMapping(value = GET_VIEW_TYPE, method = POST)
    public ResponseEntity<List<ViewType>> getViewType() {

        List<ViewType> viewTypes = catalogService.getViewType(loggedUser.getUserId());
        return new ResponseEntity<List<ViewType>>(viewTypes, HttpStatus.OK);

    }

今テスト:

 @RunWith(MockitoJUnitRunner.class)
public class CatalogRestTest {

    @InjectMocks
    private CatalogRest subject;

    @Mock
    private CatalogService catalogService;

    @Mock
    private LoggedUser loggedUser;

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test
    public void classAndItsMethodsHaveRequiredAnnotations() throws Exception {
        assertTrue(subject.getClass().isAnnotationPresent(RestController.class));
        assertTrue(subject.getClass().isAnnotationPresent(RequestMapping.class));

        Method getViewTypeMethod = subject.getClass().getMethod("getViewType");
        getViewTypeMethod.isAnnotationPresent(RequestMapping.class);
    }

    @Test
    public void getViewType_whenInvoked_returnsAListOfViewTypes() throws Exception {
        List<ViewType> viewTypes = Arrays.asList(new ViewType());

        when(loggedUser.getUserId()).thenReturn("fake user");
        when(catalogService.getViewType(eq("fake user"))).thenReturn(viewTypes);

        ResponseEntity<List<ViewType>> result = subject.getViewType();

        assertNotNull(result);
        assertNotNull(result.getBody());
        assertTrue(result.getBody().size() == 1);

        verify(catalogService, times(1)).getViewType(eq("fake user"));
    }

単体テストにスプリングを使用しないでください。スプリングはにのみ使用してintegration testingください。

于 2018-09-27T21:00:51.990 に答える
0

コンポーネントスキャン中に選択されるようにするには、サービスクラスを「@Component」アノテーションで修飾する必要がありますよね?

于 2012-08-17T09:40:42.933 に答える
0

Beanの構成を行う場所にコードを投稿できますか?ここでの問題は、Springが配線する具体的なクラスを見つけようとしていることです。

@Autowired
private FundService fundService;

Springが構成に注入するBeanを指定する必要があります。たとえば、XMLでそれを行うと、次のようになります。

<beans>

    <mvc:annotation-driven />
    <context:component-scan base-package="com.test.*" />

    <!-- Assuming FundServiceImpl is a class that implement FundService -->
    <bean id="fundService" class="com.test.admin.service.FundServiceImpl"/> 
</beans>
于 2017-05-08T07:05:58.870 に答える
0

私の場合、クラス化/パラメータ化されたテストをネストしました。

@RunWith(Enclosed.class)
@ContextConfiguration(classes = {TestX.class})
public class SimpleTest {

...
@RunWith(Parameterized.class)
public static class SimpleCheckAddTest{
.....
}

@RunWith(Parameterized.class)
public static class SimpleCheckRemoveTest{
.....
}

}

そして得た:<.....フィールドを介して表現された満たされていない依存関係......>例外のような。

@RunWith(Enclosed.class)
public class SimpleTest {

...
@RunWith(Parameterized.class)
@ContextConfiguration(classes = {TestX.class})
public static class SimpleCheckAddTest{
.....
}

@RunWith(Parameterized.class)
@ContextConfiguration(classes = {TestX.class})
public static class SimpleCheckRemoveTest{
.....
}

}
于 2019-04-16T15:16:12.977 に答える