Mockを使用したDBのソフトウエアテスト

## SQL文（insert）実行テスト①
#### ターゲットクラス
```java
public class DAO {

	/** データベースのURL */
	private String JDBC_URL = "jdbc:XXXXX";
	/** データベースのユーザー名 */
	private final String DB_USER = "sa";
	/** データベースのパスワード */
	private final String DB_PASS = "";

    /**データ追加 */
	private String sql_add = "insert into hero(name, text, location) values(?, ?, ?)";

public boolean create(Hero hero) {
		//データベース接続
    try(Connection conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASS)){
    //INSERT文にユーザー名とテキスト、場所を設定しSQLを完成
			pStmt.setString(1, hero.getUserName());
    		pStmt.setString(2, hero.getText());
            pStmt.setString(3, hero.getLocation());

int result = pStmt.executeUpdate();
			if(result != 1) {
				//登録失敗
				return false;
			}
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		}
		return true;
	}
}
``` 
### テストクラス
```java
public class DAO_Test {

//疑似環境をMockで構築
	/** テスト対象クラス */
	@InjectMocks
	DAO dao;

	/** モック */
	@Mock
	Connection conn;

	/** モック */
	@Mock
	PreparedStatement pStmt;

	/** モック*/
	@Mock
	ResultSet rs;

	@BeforeEach
	void setUp() throws Exception {
		MockitoAnnotations.initMocks(this);
	}

/**
	 *登録成功 return: true
	 * @throws SQLException
	 */

	/*	@Test
		public void create_test01() throws SQLException {
			Hero hero = new Hero("loginUser01", "text", "Tokyo");

    //eqを用いて、"insert into hero(name, text, location) values(?, ?, ?)"と
    //sql_addが同じであることを伝える
    //sql_addが実行された場合、pStmtが返されるように設定。
			 when(conn.prepareStatement(eq("insert into hero(name, text, location) values(?, ?, ?)"))).thenReturn(pStmt);

    //pStmtが実行し、1が返ってくる。
		     when(pStmt.executeUpdate()).thenReturn(1);
    
    //assertEqualsで確認
      		assertEquals(true, dao.create(hero));
		}
```

## SQL文（select）実行テスト②
### ターゲットクラス
```java
public class DAO {

	/** データベースのURL */
	private String JDBC_URL = "jdbc:XXXXX";
	/** データベースのユーザー名 */
	private final String DB_USER = "sa";
	/** データベースのパスワード */
	private final String DB_PASS = "";

/** 全件取得のSQL */
	private String sql_select = "select id,name,text from hero";

public  List<Hero> findAll() {
		List<Hero> heroList = new ArrayList<>();

		//データベース接続
		try(Connection conn = DriverManager.getConnection(JDBC_URL, DB_USER, DB_PASS)){
			//SELECT文の準備
		//	PreparedStatement pStmt = conn.prepareStatement(sql_select);
			PreparedStatement pStmt = conn.prepareStatement(sql_selectFalse);

			//SELECT文を実行
			ResultSet rs = pStmt.executeQuery();

			//SELECT文の結果をArrayListに格納
			while(rs.next()) {
				int id = rs.getInt("id");
				String userName = rs.getString("name");
				String text = rs.getString("text");
				Hero hero = new Hero(id, userName, text);
				heroList.add(hero);
			}
		}catch(SQLException e) {
			e.printStackTrace();
			return null;
		}
		return heroList;
	}
```
### テストクラス
```java
public class DAO_Test {

//疑似環境をMockで構築
	/** テスト対象クラス */
	@InjectMocks
	DAO dao;

	/** モック */
	@Mock
	Connection conn;

	/** モック */
	@Mock
	PreparedStatement pStmt;

	/** モック*/
	@Mock
	ResultSet rs;

	@BeforeEach
	void setUp() throws Exception {
		MockitoAnnotations.initMocks(this);
	}
/**
	 * heroListのサイズが1以上ある
	 * @throws SQLException
	 */
	@Test
	public void findAll_test01() throws SQLException {
		List<Hero>heroList =  dao.findAll();
		int size = heroList.size();
		assertEquals(2, size);
	}

	/**
	 * 取得したheroListのUserNameには、Aliceが含まれる
	 * @throws SQLException
	 */
	@Test
	public void findAll_test02() throws SQLException {
		List<Hero>heroList =  dao.findAll();
		boolean flg = false;

		flg = heroList.stream().anyMatch(hero -> hero.getUserName().equals("Alice"));
		assertEquals(true, flg);
	}
}
```