わかっているひとにとっては当たり前なネタなのかもですが、大いに苦しめられたのでここにお披露目します。

環境

  • Spring Boot 1.2.7
  • Java 1.8.0 102

前提

こんなレポジトリインターフェースたちがありました。

  • MenuRepository
  • CategoryRepository
  • UserRepository

ユニットテストのため、各レポジトリのモックを返すConfigurationクラスを作りました。

MyConfig.java

@Configuration
public class MyConfig {
    @Bean 
    public MenuRepository menuRepository() {
        return Mockito.mock(MenuRepository.class);
    }

    @Bean 
    public CategoryRepository categoryRepository() {
        return Mockito.mock(CategoryRepository.class);
    }

    @Bean 
    public UserRepository userRepository() {
        return Mockito.mock(UserRepository.class);
    }
}

注入先のテストはこんなんです。

MyTest.java

// 略
public class MyTest {
    @Autowired
    private MenuRepository menuRepository;

    @Autowired
    private CategoryRepository categoryRepository;

    @Autowired
    private UserRepository userRepository;
}

不可解な動き

categoryRepository@Beanメソッドは呼ばれるのに、他の@Beanメソッドは呼び出されません。

結果、注入先ではCategoryRepositoryだけがモックになっているという。。。

コンテナの中身を見ると、CategoryRepositoryだけ2つ(モックと元)あり、他は1つしかありません。

解決策

メソッド名を変えることで、無事すべての@Beanメソッドが呼び出されるようになりました。

MyConfig.java

@Configuration
public class MyConfig {
    @Bean 
    @Primary
    public MenuRepository menuRepositoryBean() {
        return Mockito.mock(MenuRepository.class);
    }

    @Bean 
    @Primary
    public CategoryRepository categoryRepositoryBean() {
        return Mockito.mock(CategoryRepository.class);
    }

    @Bean 
    @Primary
    public UserRepository userRepositoryBean() {
        return Mockito.mock(UserRepository.class);
    }
}

あと、型がかぶっているというエラーが出たので、@Primaryを付けました。

どうしてこうなるのでしょう……??