Go言語とSQLiteでユニットテスト

Go言語とデータベースSQLite3とユニットテストについて調べた2022年7月時点の情報をメモします。

## Go1.18.3をインストール
[Go言語のwebサイト](https://go.dev/)からインストールしました。
```
MacBook-Pro ~ % go version
go version go1.18.3 darwin/arm64
```
## SQLite 3.37.0をインストール
[SQLiteのwebサイト](https://www.sqlite.org/download.html)からインストールしました。
Windowsの場合は、実行ファイルsqlite3.exeをgoファイルと同じフォルダにコピー。
```
MacBook-Pro ~ % sqlite3  
SQLite version 3.37.0 2021-12-09 01:34:53
```
## gccをインストール
後ほどドライバプログラム等に利用するので、MacOSはXcode、Windowsはtmd-gccをインストール。

## go.modファイルを作成
プログラムを作成するフォルダ内で
```
>go mod init （モジュール名）
```
でgo.modファイルを作成します。
```
MacBook-Pro test_go_sqlite % pwd
/Users/***/Documents/test_go_sqlite
MacBook-Pro test_go_sqlite % go mod init test_go_sqlite
go: creating new go.mod: module test_go_sqlite
```
## SQLiteドライバプログラムのインストール
Goからsqliteを利用する為にそのドライバプログラムをインストール
```
MacBook-Pro test_go_sqlite % go get github.com/mattn/go-sqlite3
go: added github.com/mattn/go-sqlite3 v1.14.14
```

## テーブル作成
テーブルを作成するとファイル「data.sqlite3」が作成されます。
```
MacBook-Pro go_sqlite % sqlite3 data.sqlite3
SQLite version 3.37.0 2021-12-09 01:34:53
Enter ".help" for usage hints.
sqlite> CREATE TABLE "test_table" (
   ...> "id" INTEGER PRIMARY KEY AUTOINCREMENT,
   ...> "name" TEXT,
   ...> "lat" FLOAT,
   ...> "available" BIT
   ...> );
sqlite> INSERT INTO "test_table" VALUES (1,'test',35.7,true);
sqlite> select * from test_table;
1|test|35.7|1
sqlite> .exit
MacBook-Pro go_sqlite %
```

## Goプログラム作成
```Go:go_sqlite_test.go
package test_go_sqlite

import (
	"database/sql"
	"reflect"
	"testing"
	_ "github.com/mattn/go-sqlite3"
//	"fmt"
)

type Mydata struct {
	ID			int
	Name		string
	Lat			float64
	Available	bool
}

type Mydata_fetch struct {
	ID			int
	Name		string
}

func fetch(con *sql.DB)[]Mydata_fetch{
	return_fetch := make([]Mydata_fetch,0)
	q := "select * from test_table"
	re, er := con.Query(q)
	if er != nil {
		panic(er)
	}

	for re.Next() {
		var md Mydata
		er := re.Scan(&md.ID, &md.Name, &md.Lat, &md.Available)
		if er != nil {
			panic(er)
		}
		add := Mydata_fetch{ID:md.ID, Name:md.Name}
		return_fetch = append(return_fetch, add)
	}
	return return_fetch
}

func TestSomething(t *testing.T) {
	con, er := sql.Open("sqlite3","data.sqlite3")
	if er != nil {
		panic(er)
	}
	defer con.Close()

	actual := fetch(con)
//	fmt.Println(actual)
	expected := make([]Mydata_fetch,0)
	add := Mydata_fetch{1, "test"}
	expected = append(expected, add)
//	fmt.Println(expected)

	if !(reflect.DeepEqual(actual, expected)) {
		t.Errorf("Test Error!!!\n")
	}
}
```
## ユニットテスト実行
```
MacBook-Pro test_go_sqlite % pwd
/Users/***/Documents/test_go_sqlite
MacBook-Pro test_go_sqlite % ls
data.sqlite3            go.mod                  go.sum                  go_sqlite_test.go
MacBook-Pro test_go_sqlite % go test -v
=== RUN   TestSomething
--- PASS: TestSomething (0.00s)
PASS
ok      test_go_sqlite  0.285s
```

以上、Go言語でsqlite3を使ってデータを読み出してユニットテストを行う流れでした。

## 参考情報
https://qiita.com/Utr/items/5eca8b61e1857d193587

https://qiita.com/taksatou@github/items/48b22d6d37e99a6c21cc

https://qiita.com/uchiko/items/64fb3020dd64cf211d4e

https://qiita.com/KoyoTakenoshita/items/522a4ff1a81b51e8d5b3

[Go のモジュール管理【バージョン 1.17 改訂版】](https://zenn.dev/spiegel/articles/20210223-go-module-aware-mode)
[【Go言語】構造体を要素に持つスライスの作成・要素追加・初期化方法まとめ](https://nishinatoshiharu.com/initialize-structure-slice/)
[booleanを反転（トグル）させる方法](https://www.deep-rain.com/programming/tips/633)