Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationEventAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
0
Help us understand the problem. What are the problem?

More than 3 years have passed since last update.

@sengoku

[Java][Spring] Spring Boot 1.4 -> 1.2 ダウングレードメモ

こんなことをするひとはいないと思いますが、せっかく苦しんだのでメモしておきます。

この文章の表記について

:grin: 1.4: 1.4の場合のやりかたです。
:smirk: 1.2: 1.2の場合のやりかたです。

実装関係

@EntityScan

:grin: 1.4: org.springframework.boot.autoconfigure.domain.EntityScan
:smirk: 1.2: org.springframework.boot.orm.jpa.EntityScan

DI

:grin: 1.4: 自明であれば@Autowiredを付けなくてもDIしてくます。
:smirk: 1.2: @Autowired付けましょう。

テスト関係

テストランナー

:grin: 1.4: @RunWith(SpringRunner.class)
:smirk: 1.2: @RunWith(SpringJUnit4ClassRunner.class)

Springを使ったテスト

:grin: 1.4: @SpringBootTestを付ける
:smirk: 1.2: @SpringApplicationConfiguration(classes = アプリケーションクラス)を付ける

データベース統合テスト

:grin: 1.4: @DataJpaTestをテストクラスに付ける。
:smirk: 1.2: ちと大変。

@DataJpaTestはこんなことをしてくれているそうです。

  1. インメモリデータベースを設定
  2. Hibernate/Spring Data/Datasourceを設定
  3. @EntityScanを実行
  4. SQLログを有効化

全部がんばらないといけないかと思いましたが、これだけのことをやれば大丈夫そうです。

  1. @EntityScan@EnableJpaRepositoriesを付けたアプリケーションコンテキストクラスを作成。
  2. TestEntityManagerクラスを作成(1.4からぱくる)
  3. TestEntityManagerを返すBeanを作成(1.4からぱくる)
  4. テストクラスに@Transactional@SpringApplicationConfigurationを付ける。

順番にやっていきます。

@EntityScan@EnableJpaRepositoriesを付けたアプリケーションコンテキストクラスを作成

TestApplication.java
@SpringBootApplication
@EnableJpaRepositories(レポジトリクラスの場所)
@EntityScan(エンティティクラスの場所)
@EnableJpaAuditing // これは今回関係ない
public class TestApplication {

}

TestEntityManagerクラスを作成(1.4からぱくる)

元ソースはここにあります。
https://github.com/spring-projects/spring-boot/blob/master/spring-boot-test-autoconfigure/src/main/java/org/springframework/boot/test/autoconfigure/orm/jpa/

TestEntityManager.java
public class TestEntityManager {

    private final EntityManagerFactory entityManagerFactory;

    public TestEntityManager(EntityManagerFactory entityManagerFactory) {
        Assert.notNull(entityManagerFactory, "EntityManagerFactory must not be null");
        this.entityManagerFactory = entityManagerFactory;
    }

    public <E> E persist(E entity) {
        getEntityManager().persist(entity);
        return entity;
    }

    public void flush() {
        getEntityManager().flush();
    }

    public <E> E persistAndFlush(E entity) {
        persist(entity);
        flush();
        return entity;
    }

    public void detach(Object entity) {
        getEntityManager().detach(entity);
    }

    public <E> E find(Class<E> entityClass, Object primaryKey) {
        return getEntityManager().find(entityClass, primaryKey);
    }

    public final EntityManager getEntityManager() {
        EntityManager manager = EntityManagerFactoryUtils
                .getTransactionalEntityManager(this.entityManagerFactory);
        Assert.state(manager != null, "No transactional EntityManager found");
        return manager;
    }
}

TestEntityManagerを返すBeanを作成(1.4からぱくる)

TestEntityManagerConfigure.java
@Configuration
@AutoConfigureAfter(HibernateJpaAutoConfiguration.class)
public class TestEntityManagerConfigure {

    @Bean
    @ConditionalOnMissingBean
    public TestEntityManager testEntityManager(
            EntityManagerFactory entityManagerFactory) {
        return new TestEntityManager(entityManagerFactory);
    }

}

テストクラスに@Transactional@SpringApplicationConfigurationを付ける

MySomeRepositoryTest.java
import org.springframework.transaction.annotation.Transactional;

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = TestApplication.class)
@Transactional
public class MySomeRepositoryTest {

    @Autowired
    private MySomeRepository instance;

    @Autowired
    private TestEntityManager em;

    @Test
    public void testSomeMethod {
     // ...
    }

}


モック化したインスタンスをインジェクトする

:grin: 1.4: モック化したいインスタンス変数に@MockBeanを付ける
:smirk: 1.2: モック化したインスタンスを返す@Beanを定義して@Primaryを付ける

1.4の場合

MySomeTest.java
    @MockBean
    private MyTargetClass mock;

1.2の場合

特定の@Configurationクラスだけ有効になるように、@Profileを付けています。

MySomeTest.java
@ActiveProfiles("MySomeTest")
public class MySomeTest {
    @Autowired
    private MyTargetClass mock;
}
MySomeTestConfig.java
@Configuration
@Profile("MySomeTest")
public class MySomeTestConfig {
    @Bean
    @Primary
    public MyTargetClass myTargetClass() {
        return Mockito.mock(MyTargetClass.class);
    }
}

旅は続く。。。

また何か発見があったら追記していきます。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
0
Help us understand the problem. What are the problem?