2017-09-15 8 views
1

내 응용 프로그램이 Spring Boot, Hibernate, JUnit으로 빌드됩니다. 메모리 테스트에 H2 데이터베이스를 사용하고 SQL 도구로 H2 데이터베이스에 연결할 수있는 빈을 만들었습니다.Spring Junit org.h2.jdbc.JdbcSQLException : 포트 "9092"(포트가 사용 중일 수 있음)를 여는 예외.

@Configuration 
public class H2DataBaseTestConfig { 
    @Bean(initMethod = "start", destroyMethod = "stop") 
    public Server h2Server() throws SQLException { 
     return Server.createTcpServer("-tcp", "-tcpAllowOthers", "-tcpPort", "9092"); 
    } 
} 

나는 하나 개의 테스트를 실행하면 그것은 잘 작동하지만 내가 모든 테스트를 실행하면 나는 두 번째, 모든 다음 테스트 클래스

Exception opening port "9092" (port may be in use) 

스프링 애플리케이션 컨텍스트를 만들려고과 같은이 외모에 오류가 다음 테스트 클래스가 실행될 때마다 빈을 시작한다. 모든 테스트를 실행하고이 Bean을 작동 시키려면 어떻게해야합니까?

업데이트

으로 많은 사람들이 테스트 클래스의 주석을 언급, 나는 여기에 표시됩니다 :

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(IndeedScraper.class) 
@TestPropertySource(locations="classpath:test.properties") 

을 내가 몇 @Configuration 클래스가 두 데이터베이스 연결/거래/엔티티 관리 클래스 및 여기에 설명 된 h2Server bean. h2Server 콩 빌더 클래스는, SRC/테스트/자바에 저장된 참조 SRC/메인/자바에서 다른 @Configuration 클래스

최종 업데이트

여기에 전체 스택 추적하는 동안 :

java.lang.IllegalStateException: Failed to load ApplicationContext 
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:124) 
    at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:83) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.injectDependencies(DependencyInjectionTestExecutionListener.java:117) 
    at org.springframework.test.context.support.DependencyInjectionTestExecutionListener.prepareTestInstance(DependencyInjectionTestExecutionListener.java:83) 
    at org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:228) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.createTest(SpringJUnit4ClassRunner.java:230) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:249) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:89) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) 
    at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:193) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192) 
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'h2Server' defined in class path resource [healthjobs/scraper/H2DataBaseTestConfig.class]: Invocation of init method failed; nested exception is org.h2.jdbc.JdbcSQLException: Exception opening port "9092" (port may be in use), cause: "java.net.BindException: Address already in use (Bind failed)" [90061-192] 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1578) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:545) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:772) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:760) 
    at org.springframework.boot.SpringApplication.createAndRefreshContext(SpringApplication.java:360) 
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) 
    at org.springframework.boot.test.SpringApplicationContextLoader.loadContext(SpringApplicationContextLoader.java:98) 
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:98) 
    at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:116) 
    ... 25 more 
Caused by: org.h2.jdbc.JdbcSQLException: Exception opening port "9092" (port may be in use), cause: "java.net.BindException: Address already in use (Bind failed)" [90061-192] 
    at org.h2.message.DbException.getJdbcSQLException(DbException.java:345) 
    at org.h2.message.DbException.get(DbException.java:168) 
    at org.h2.util.NetUtils.createServerSocketTry(NetUtils.java:199) 
    at org.h2.util.NetUtils.createServerSocket(NetUtils.java:165) 
    at org.h2.server.TcpServer.start(TcpServer.java:232) 
    at org.h2.tools.Server.start(Server.java:484) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:498) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeCustomInitMethod(AbstractAutowireCapableBeanFactory.java:1706) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1645) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1574) 
    ... 40 more 
Caused by: java.net.BindException: Address already in use (Bind failed) 
    at java.net.PlainSocketImpl.socketBind(Native Method) 
    at java.net.AbstractPlainSocketImpl.bind(AbstractPlainSocketImpl.java:387) 
    at java.net.ServerSocket.bind(ServerSocket.java:375) 
    at java.net.ServerSocket.<init>(ServerSocket.java:237) 
    at java.net.ServerSocket.<init>(ServerSocket.java:128) 
    at org.h2.util.NetUtils.createServerSocketTry(NetUtils.java:195) 
    ... 50 more 
+0

모든 테스트 사례에 대해 bean을 만드는 대신 @Autowire를 사용할 수 있습니다. – Nidhi257

+0

이 'Server.createTcpServer'를 수행하는 특별한 이유가 있습니까? Springboot가 자동으로 h2 데이터베이스에 연결합니다. – pvpkiran

+0

@ Nidhi257 무슨 뜻인지 설명해 주시겠습니까? Autowire가 bean 생성을 방지하는 방법? – Pavlo

답변

1

한이 integration test tutorial 설명도 Spring documentation

에 컨텍스트 캐싱 설명에주의로 테스트 클래스 사이에 Spring 컨텍스트를 공유 할 수 있습니다에있는 모든 시험 방법에 대해 한 번 만든 것

@RunWith(SpringJUnit4ClassRunner.class) 
... 
@ContextConfiguration(classes=H2DataBaseTestConfig.class, loader=AnnotationConfigContextLoader.class) 
public class SomeServiceTest { 
    ... 

참고이 방법은 SpringBoot 통합에 의존하지 않는, 다음과 같이 당신의 단위 테스트 클래스에 같은 실행 컨텍스트를 공유 할 수있다

는 H2 연결이 필요 단위 테스트의 모든 주석을하려고 다른 답변에서 언급 된 테스트 지원 이 스레드에서. 그렇지 않은 명백한 것으로

업데이트

, 당신은 당신의 통합 테스트 클래스에서 필요한 모든 컨텍스트 조각의 상위을 반영하기 위해이 같은 @ContextConfiguration(classes={H2Config.class, MyConfigFromSrcTest.class, MyConfigFromSrcMain.class, ...}, ...의 모든 다른 필요한 @ 구성-주석 클래스를 나열해야 할 수도 있습니다. 결과 컨텍스트는 캐시 키와 같은 구성 클래스의 정확한 집합을 사용하여 캐싱됩니다.

+0

이것은 모든 테스트 클래스가 시작되기 전에 H2DataBaseTestConfig 클래스 bean이로드된다는 것을 의미합니까? 그렇다면, 이미 모든 테스트 클래스가 실행될 때마다 인스턴스화 된 bean이 이미 있습니다. 아니면 모든 테스트 클래스간에 H2DataBaseTestConfig를 공유합니까? H2DataBaseTestConfig 클래스 이름 근처에서 Configuration 주석을 삭제해야합니까? – Pavlo

+0

'@ Configuration' 주석은 그대로 두십시오. 설명한대로'@ ContextConfiguration'을 추가하면, 새로운 단위 테스트 클래스가 실행될 때마다 컨텍스트를 생성하는 대신 Spring이 동일한 H2DataBaseTestConfig로 구성된 컨텍스트를 캐시하고 재사용하도록합니다. – Kostiantyn

+0

@ContextConfiguration 다른 Autowired beans를 테스트 클래스가 더 이상 작동하지 않습니다 - org.springframework.beans.factory.BeanCreationException. 내 질문 업데이트를 참조하십시오. – Pavlo

1
@Before 
public void setUp() { 
    createTCPConnection(); 
} 

@After 
public void endTest() { 
    closeTCPConnection(); 
} 

@Test 
public void firstTest() { 
    doTest(1); 
} 

@Test 
public void secondTest() { 
    doTest(2); 
} 

모든 실행중인 테스트는 전후로 호출됩니다. 따라서, 연결은 그 클래스와 옵션의

+0

테스트 컨텍스트 캐시가있는 문제 솔루션을 발견 한 경우이를 확인하지 않았습니다. 비록 당신의 아이디어가 효과가있을 것 같아 보이지만. 감사. – Pavlo