LoginSignup
2
0

More than 3 years have passed since last update.

Golang テスト実行時の循環参照でハマった話

Posted at

GodeAPIを作り始めたのはいいのですが、コントローラーのテストを行なった際に循環参照が発生してハマりました。フレームワークはginを使用しています

循環参照が発生するソース

/controller/user_controller_test.go
package controller

import (
>..."github.com/ashiato/config"
>..."github.com/ashiato/db"
>..."github.com/stretchr/testify/assert"
>..."net/http"
>..."net/http/httptest"
>..."testing"
)

//func TestLoginSuccess(t *testing.T) {
func TestIndexSuccess(t *testing.T) {

>...//DB接続
>...db.Init()

>...//ルーティング設定
>...router := config.Router{}
>...ro := router.LoadRoute()

>...w := httptest.NewRecorder()
>...req, _ := http.NewRequest("GET", "/user", nil)
>...ro.ServeHTTP(w, req)

>...assert.Equal(t, 200, w.Code)
}
/config/router.go
package config

import (
>..."github.com/ashiato/controller"
>..."github.com/gin-gonic/gin"
)

type Router struct{}

// Init is initialize server
func (ro Router) Init() {
>...r := ro.LoadRoute()
>...r.Run()
}

func (ro Router) LoadRoute() *gin.Engine {
>...r := gin.Default()

>...u := r.Group("/user")
>...{
>...>...ctrl := controller.UserController{}
>...>...u.GET("", ctrl.Index)
>...}

>...return r
}

テストはhttps://gin-gonic.com/ja/docs/testing/ に習ってrouter.goのLoadRouteを呼び出しています。そのためgithub.com/ashiato/configパッケージを読み込んでいるのですが、
router.goはコントローラーのメソッドを呼び出しているためgithub.com/ashiato/controllerが必要です、この時循環参照が発生します。

configに入っているrouterをcontrollerに持っていくとソースの見通しが悪くなり、逆もまた然り、
かと行ってテストでルーターを作成するのは2重管理になってしまい嫌です。

そんな時こちらの記事をでこんな記載がありました

抜粋

Goは同じディレクトリ以下に複数のpackage名を許さないが、例外的にxxxパッケージとxxx_testパッケージは同じディレクトリに共存できる。
当然異なるパッケージになるので、非公開メソッドなどは参照できなくなるが、循環参照を回避できる。
また、非公開な機能をexport_test.goを介してアクセスすることもできる。

なるほど、そういうことでしたか!

ということで修正します

/controller/user_controller_test.go
package controller_test    // 変更

import (
>..."github.com/ashiato/config"
>..."github.com/ashiato/db"
>..."github.com/stretchr/testify/assert"
>..."net/http"
>..."net/http/httptest"
>..."testing"
)

//func TestLoginSuccess(t *testing.T) {
func TestIndexSuccess(t *testing.T) {

>...//DB接続
>...db.Init()

>...//ルーティング設定
>...router := config.Router{}
>...ro := router.LoadRoute()

>...w := httptest.NewRecorder()
>...req, _ := http.NewRequest("GET", "/user", nil)
>...ro.ServeHTTP(w, req)

>...assert.Equal(t, 200, w.Code)
}

これでうまくいきました、まだまだGolangと仲良くなれません。

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0