2015-01-23 2 views
1

는 내가 명시 적으로로드 할 스프링 구성 XML 파일이 있는데 그것은이 내부에 있습니다Spring이 @Configuration을 테스트에서 사용하지 못하게하는 방법은 무엇입니까?

<context:annotation-config/> 
<context:component-scan base-package="my.path" /> 

나는 시험이처럼로드 해요을 :

new ClassPathXmlApplicationContext(new String[]{"/beans.xml"}) 

문제는이 검사가 base-package 아래에있는 패키지에 있기 때문에이 검사가 다른 검사 안에 중첩 된 @Configuration을 볼 수 있다는 것입니다. 내 테스트를 위해 이것은 바람직하지 않은 행동입니다. 이 문제를 방지 할 수있는 방법이 있습니까? 이 component-scan@Configuration 클래스를로드하지 않습니다. 이것에 대해 어떻게

+0

약간 더 시급한 질문은, 왜 실제 클래스 경로를 오염하는 테스트 클래스와 그 구성을 허용하고? – Makoto

+0

@Makoto 나는 다른 방법이 있을지 모르겠다. 테스트가 클래스 패스를 실행하여 실행하지 않습니까? 그 밖에 어떻게 달릴 수 있니? 내가 작성한이 블로그 기사는 내가 달성하고자하는 것을 자세하게 설명합니다 (나는이 문제에 대해 물었 기 때문에이 질문을합니다). http : // www.sleepeasysoftware.com/how-to-mock-out-a-deeply-nested-class-in-spring-withgoing-going-insane/ –

+0

오. IntelliJ에 포트를 꽂기 만하면됩니다. – Makoto

답변

2

: 그

@RunWith(SpringJUnit4Runner.class) 
@ContextConfiguration(locations={"classpath:/path/to/beans.xml"}) 
public class SpringDatabaseTest { 

} 

참고 인 IntelliJ의와 :

<context:component-scan base-package="my.path" > 
    <context:exclude-filter type="annotation" 
     expression="org.springframework.context.annotation.Configuration" />   
</context:component-scan> 
+0

정말 대단합니다. 이 방법으로 필터링 할 수있는 방법이 있습니까? 테스트 클래스에 중첩 된'@ Configuration'을 제외 하시겠습니까? –

2

일반 방법은 봄과 시험에서이 문제를 피하기 위해 테스트가 자신의 상황에 맞는 구성을로드하는 것입니다 구성 요소 스캔 (꽤 정확함)을 사용하면 번거로운 구성이 더 이상 나타나지 않습니다.

enter image description here

이제 테스트의 목표가 문제가됩니다. 당신은 시험을 의도합니까? 배선이 작동하고 데이터를 다시 가져올 것이라고 가정하고 싶습니까? 유선과의 실제 상호 작용을 확인 하시겠습니까?

이전 버전을 수행하려면 은이를 위해 Spring을 사용하지 마십시오. 대신 Mockito를 전체적으로 사용하십시오. 여기 저기에 몇 개의 콩을 주입하는 것에는 의미가 없지만 나머지는 조롱합니다. 그것은 혼란스럽고 일치하지 않는 테스트로 이어집니다.

모의 작업을 주입하는 데 필요한 클래스에 몇 가지 setter 속성을 추가해야하며 직접 초기화해야하지만 어쨌든 init 함수로 처리 할 수 ​​있습니다.

링크 된 블로그에서 이것은 조롱 된 데이터베이스 테스트의 전체 코드입니다.

package mavensnapshot; 

import org.junit.Before; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Answers; 
import org.mockito.InjectMocks; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

import static org.mockito.Mockito.doNothing; 
import static org.mockito.Mockito.verify; 

@RunWith(MockitoJUnitRunner.class) 
public class MockDatabaseTest { 

    @Mock 
    private Database mockRepo; 

    @InjectMocks 
    private Middle middle; 

    @Before 
    public void init() { 
     End end = new End(); 
     end.setDatabase(mockRepo); 
     middle.setEnd(end); 
    } 

    @Test 
    public void testReplaceRepositoryWithMock() { 
     doNothing().when(mockRepo).save(); 
     middle.useEnd(); 
     verify(mockRepo).save(); 
    } 
} 

후자를 수행하려는 경우 은 절대적으로 스프링을 사용하십시오. 그 주위에는 둔기가없는 다른 방법이 없습니다. 이 시점에서, 당신은 지금 당신이 mock으로 할 수있는 것처럼 단순한은 아니고 코드와의 완벽한 상호 작용을 검증해야합니다. 이는 또한 어떻게 설정 했느냐에 달려 있습니다. 차라리 각각의 클래스가 자체 테스트를 얻는 대신 그 아래의 레이어가 잘 작동한다고 가정하고 가장 낮은 레이어에서 구체적인 테스트를 수행하고 가장 높은 레이어에서보다 완벽한 통합 테스트를 도입하는 것이 좋습니다.

같은 프로젝트, 시험의 다른 스타일 :

package mavensnapshot; 

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

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:/beans.xml"}) 
public class SpringDatabaseTest { 

    @Autowired 
    private Middle middle; 

    @Test 
    public void testMiddle() { 
     middle.useEnd(); 
    } 
} 
+0

나는 indepth 답장을 고맙게 생각합니다. 그리고 나는 사람들이 단위 테스트를 작성하는 방법이라고 생각합니다. 극단적으로 말하자면, 이것은 실제로 내 질문에 답하지 않고 "대신에 다른 일을하라"고 말합니다. 봄 테스트 코드를 작성하는 대다수의 개발자가 여러분에게 동의하지만, 거기에는 다른 철학이 있습니다. 개인적으로, 나는 이것을 따른다 : http://vimeo.com/68375232 –

+0

그 비디오는 또한 매우 길고 대부분은 볼 시간이 없다 (그러나 나는 매우 추천한다). * Collaborator Isolation *에 대한 부분을 주목하십시오 : "그러나 모든 단위 테스터가이 격리를 사용하지는 않습니다. 실제로 xunit 테스트가 90 년대에 시작되었을 때 우리는 공동 작업자와의 의사 소통이 어색 할 때 (예 : 원격 신용 카드 확인 시스템) 분리를 시도하십시오. " –