【問題解決】MyBatisのテストで、「No qualifying bean of type～」というエラーが発生



# 環境
* mybatis-spring-boot-starter: 1.3.1
    - mybatis: 3.4.5
* mybatis-spring-boot-starter-test: 1.3.1
* postgresql jdbc : 42.1.4
* Spring Boot 1.5.9
* Java8
* PostgreSQL 9.6

# やりたいこと
MyBatisを使ってDBにアクセスしています。
今、`HotelDao.java`の`findById`メソッドのテストを実施したいです。

```java:HotelDao.java
@Component
public class HotelDao {

	private final SqlSession sqlSession;

	public HotelDao(SqlSession sqlSession) {
		this.sqlSession = sqlSession;
	}

	public Hotel findById(long id) {
		return this.sqlSession.selectOne("findHotelById", id);
	}

}
```


# 問題

以下のような、`findById`メソッドを確認するテストコードを作成しました。

```java:HotelDaoTest.java
@RunWith(SpringRunner.class)
@MybatisTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class HotelDaoTest {

	@Autowired
	private HotelDao hotelDao;

	@Test
	public void test() {
		Hotel hotel = hotelDao.findById(1);
		System.out.println(hotel);
	}

}
```

JUnitでテストメソッドを実行すると、以下のエラーがコンソールに表示されました。


```txt:console

2018-01-24 23:03:54.990 ERROR 22456 --- [           main] o.s.test.context.TestContextManager      : Caught exception while allowing TestExecutionListener [org.springframework.boot.test.autoconfigure.SpringBootDependencyInjectionTestExecutionListener@6a472554] to prepare test instance [com.example.demo2.mybatis.dao.HotelDaoTest@275710fc]

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.example.demo2.mybatis.dao.HotelDaoTest': 
Unsatisfied dependency expressed through field 'hotelDao'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No qualifying bean of type 'com.example.demo2.mybatis.dao.HotelDao' available: expected at least 1 bean which qualifies as autowire candidate. 
Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
...
```

※読みやすくするため、適切な箇所に改行を入れました

# 原因
エラーの最後の方では「No qualifying bean of type '～.HotelDao' available: expected at least 1 bean which qualifies as autowire candidate. 」、すなわち「`HotelDao`のbeanが見つからない」と言われています。

`@MyBatisTest`を付与すると、`@Component `のbeanはロードされないため、beanが見つからないようです。

>Also regular @Component beans will not be loaded into the ApplicationContext.

※ http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-test-autoconfigure/ 引用

# 解決
`@Import`を使って、`HotelDao`のbeanをロードしました。


```java:HotelDaoTest.java
@RunWith(SpringRunner.class)
@MybatisTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
@Import(HotelDao.class)
public class HotelDaoTest {

	@Autowired
	private HotelDao hotelDao;

	@Test
	public void test() {
		Hotel hotel = hotelDao.findById(1);
		System.out.println(hotel);
	}

}
```

http://www.mybatis.org/spring-boot-starter/mybatis-spring-boot-test-autoconfigure/#Test_for_DAO_pattern: 参考

# 補足

## `@Mapper`の場合、`@Import`は不要

```java:CityMapper.java
@Mapper
public interface CityMapper {
    @Select("select * from city")
	City findCity();
}
```

```java:CityMapperTest.java
@RunWith(SpringRunner.class)
@MybatisTest
@AutoConfigureTestDatabase(replace = Replace.NONE)
public class CityMapperTest  {

	@Autowired
	CityMapper cityMapper;

	@Test
	public void test() {
		City city = cityMapper.findCity();
		System.out.println(city);
	}

}
```

# 参考にしたサイト

* [Spring BootでNo qualifying bean of typeが出た時の原因と対応](https://qiita.com/NagaokaKenichi/items/058a7243bd2948de7553)
* [mybatis-spring-boot-starter 1.3の変更点](https://qiita.com/kazuki43zoo/items/3f94d2049d331f81e6f5)
* [MybatisTest.java - GitHub](https://github.com/mybatis/spring-boot-starter/blob/master/mybatis-spring-boot-test-autoconfigure/src/main/java/org/mybatis/spring/boot/test/autoconfigure/MybatisTest.java)