복붙노트

[SPRING] 테스트 클래스가 더러워진 후에 Spring JUnit 애플리케이션 컨텍스트를 어떻게 재설정합니까?

SPRING

테스트 클래스가 더러워진 후에 Spring JUnit 애플리케이션 컨텍스트를 어떻게 재설정합니까?

저는 Spring 3.1.1.RELEASE, JUnit 4.8.1 및 HSQL 2.7.7 메모리 내장 데이터베이스를 사용하고 있습니다. 나는 하나의 테스트 클래스에 주석을 달았다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-trainingSessionServiceContext.xml" })
@DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
public class TrainingSessionServiceTest  
{

문제는 "mvn clean test"를 실행하면 메모리 내 데이터베이스가 손상되어 다시 생성되지 않기 때문에 위의 클래스가 실패한 후에 모든 테스트 클래스가 실행되는 것입니다. 나는 오류를 얻는다.

org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: CB_ORGANIZATION" type="javax.persistence.PersistenceException">javax.persistence.PersistenceException:   org.hibernate.exception.SQLGrammarException: user lacks privilege or object not found: CB_ORGANIZATION
    at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1360)
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:817)
    at org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:771)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:240)
    at $Proxy46.find(Unknown Source)
    at org.mainco.subco.organization.repo.OrganizationDaoImpl.findById(OrganizationDaoImpl.java:77)
    at org.mainco.subco.pd.repo.LinkDaoTest.createDummyLink(LinkDaoTest.java:686)
    at org.mainco.subco.pd.repo.LinkDaoTest.testSaveLink(LinkDaoTest.java:67)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)

여기에 예외를주는 테스트 클래스 (위의 클래스를 실행 한 후)를 설정하는 방법이 나와 있습니다.

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:test-context.xml" })
public class LinkDaoTest extends AbstractTransactionalJUnit4SpringContextTests
{

각 테스트 클래스를 실행하기 전에 응용 프로그램 컨텍스트를 원래 상태로 복원 할 수있는 방법이 있습니까? "TrainingSessionServiceTest"클래스가 AbstractTransactionalJUnit4SpringContextTests를 확장하도록 만들고 싶지 않습니다. 내 응용 프로그램 컨텍스트의 관련 부분은 다음과 같습니다.

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver"/>
    <property name="url" value="jdbc:hsqldb:mem:pd" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
    <property name="jpaVendorAdapter">
        <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
    </property>
    <property name="persistenceXmlLocation" value="classpath:META-INF/test-persistence.xml"/>
    <property name="persistenceUnitName" value="testingDatabase"/>
    <property name="dataSource" ref="dataSource"/>
</bean>

<bean id="sharedEntityManager" class="org.springframework.orm.jpa.support.SharedEntityManagerBean">
   <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
    <property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>

<tx:annotation-driven />

<jdbc:embedded-database id="embedded" type="HSQL"/> 
<jdbc:initialize-database data-source="dataSource">
    <jdbc:script location="classpath:db-test-data.sql"/>    
</jdbc:initialize-database>  

해결법

  1. ==============================

    1.재설정을 강제로 수행하려면 @DirtiesContext를 사용하십시오. 예를 들면 :

    재설정을 강제로 수행하려면 @DirtiesContext를 사용하십시오. 예를 들면 :

    @ContextConfiguration(classes={BlahTestConfig.class})
    @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
    public class SomeTest {
    
        @Autowired XXXX xx;
        @Autowired YYYY yy;
    
        @Before
        public void setUp() {
            MockitoAnnotations.initMocks(this);
            when(YYYY.newYY()).thenReturn(zz);
        }
    
        @Test
        public void testSomeTest() {
            XX.changeSomething("StringTest");
            XX.doSomething();
            check_for_effects();
        }
    
        @Test
        public void testSomeOtherTest() {
            XX.changeSomething("SomeotherString");
            XX.doSomething();
            check_for_effects();
        }
    

    봄 워드 프로세서에서

    기본 Spring ApplicationContext가 테스트 실행 중에 다음과 같이 dirtied (수정)되었음을 나타냅니다. 테스트 통과 여부와 관계없이 닫아야합니다.

    테스트가 컨텍스트를 수정 한 경우 (예 : bean 정의 교체)이 주석을 사용하십시오. 후속 테스트에는 새로운 컨텍스트가 제공됩니다. [참고] @DirtiesContext와 JUnit 3.8의 한계

    > JUnit 3.8 환경에서 @DirtiesContext는 메소드에서만 지원되므로 클래스 수준에서는 지원되지 않습니다.

    @DirtiesContext는 같은 클래스 내에서 클래스 수준 및 메서드 수준의 주석으로 사용할 수 있습니다. 그러한 시나리오에서, ApplicationContext는 전체 주석 클래스와 마찬가지로 주석이 달린 메소드 후에 dirty로 표시됩니다. ClassMode가 AFTER_EACH_TEST_METHOD로 설정되면, 컨텍스트는 클래스의 각 테스트 메소드 다음에 dirty로 표시됩니다.

    @DirtiesContext
    public class ContextDirtyingTests {
        // some tests that result in the Spring container being dirtied
    }
    
    @DirtiesContext(classMode = ClassMode.AFTER_EACH_TEST_METHOD)
    public class ContextDirtyingTests {
        // some tests that result in the Spring container being dirtied
    }
    
    @DirtiesContext
    @Test
    public void testProcessWhichDirtiesAppCtx() {
        // some logic that results in the Spring container being dirtied
    }
    

    응용 프로그램 컨텍스트가 dirty로 표시되면 테스트 컨텍스트의 캐시에서 제거되고 닫힙니다. 따라서 기본 Spring 컨테이너는 동일한 리소스 위치 집합을 가진 컨텍스트가 필요한 모든 후속 테스트를 위해 다시 작성됩니다.

  2. from https://stackoverflow.com/questions/14718088/how-do-you-reset-spring-junit-application-context-after-a-test-class-dirties-it by cc-by-sa and MIT license