概要
Golangのユニットテストをtestify/suitを用いて書きました。
https://github.com/stretchr/testify/tree/master/suite
Golangのテスト時のモックに関しても一緒に書きたいと思います。
実装
実際のテストの中身は今回の記事の対象外の為、一番簡易なMVCで言う所のController層のテストで紹介します。
controller.go
package controller
import (
"article/api/service"
"net/http"
"github.com/gin-gonic/gin"
)
type Controller struct {
service service.ServiceInterface
}
func NewController(service service.ServiceInterface) *Controller {
return &Controller{service: service}
}
type ControllerInterface interface {
GetArticleController(c *gin.Context)
}
func (controller Controller) GetArticleController(c *gin.Context) {
articles := controller.service.GetArticleService()
c.JSON(http.StatusOK, articles)
}
controller.goから参照されており、テストではモックにするservice.goは以下になります。
service.go
package service
import (
"fmt"
"github.com/gin-gonic/gin"
"article/api/dao"
"article/api/util"
)
type Service struct {
dao dao.DaoInterface
}
func NewService(dao dao.DaoInterface) *Service {
return &Service{dao: dao}
}
type ServiceInterface interface {
GetArticleService() []util.Article
}
func (s Service) GetArticleService() []util.Article {
//some code
}
実際のcontroller.goのテストファイルは以下のようになります。
controller_test.go
package controller
import (
"article/api/service"
"article/api/util"
"net/http/httptest"
"testing"
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)
type MockServiceInterface struct {
}
func (_m *MockServiceInterface) GetArticleService() []util.Article {
return nil
}
type ControllerSuite struct {
suite.Suite
controller *Controller
service service.ServiceInterface
}
func (s *ControllerSuite) SetupTest() {
s.controller = NewController(s.service)
s.controller.service = &MockServiceInterface{}
}
func TestControllerSuite(t *testing.T) {
suite.Run(t, new(ControllerSuite))
}
func (s *ControllerSuite) TestGetArticleController() {
c, _ := gin.CreateTestContext(httptest.NewRecorder())
s.controller.GetArticleController(c)
assert.Equal(s.T(), 200, c.Writer.Status())
}
-
MockServiceInterface
に上書きすることにより、モックを実現しています。 - 今回はstatus codeが正常であることだけが分かればいいテストにするので、
GetArticleService()
の返り値はnilにしています。
実際にテストを実行してみます。
terminal
$ go test -v
=== RUN TestControllerSuite
=== RUN TestControllerSuite/TestGetArticleController
[GIN-debug] [WARNING] Running in "debug" mode. Switch to "release" mode in production.
- using env: export GIN_MODE=release
- using code: gin.SetMode(gin.ReleaseMode)
--- PASS: TestControllerSuite (0.00s)
--- PASS: TestControllerSuite/TestGetArticleController (0.00s)
PASS
ok article/api/controller 0.044s
passしました。
全体像を把握したい場合は、以下のgithubをご参照ください。
https://github.com/jpskgc/article/tree/master/api