LoginSignup
2
3

More than 3 years have passed since last update.

testify/suitとモックを用いてgolangのユニットテストを作成する

Last updated at Posted at 2019-09-11

概要

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

2
3
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
3