私のプロジェクトは、コントローラー、サービス、モデルの3つの主要コンポーネントに分かれています。 URIを介してルートが照会されると、コントローラーが呼び出され、コントローラーがサービスを呼び出してモデルと対話し、モデルはgormを介してデータベースと対話します。
コントローラーの単体テストを作成しようとしていますが、ジンレイヤーをモックしながらサービスレイヤーを適切にモックする方法を理解するのに苦労しています。モックされたginコンテキストを取得できますが、コントローラーメソッド内でサービスレイヤーをモックできません。以下は私のコードです:
resourceController.go
package controllers
import (
"MyApi/models"
"MyApi/services"
"github.com/gin-gonic/gin"
"net/http"
)
func GetResourceById(c *gin.Context) {
id := c.Param("id")
resource, err := services.GetResourceById(id)
if err != nil {
c.JSON(http.StatusBadRequest, gin.H{"status": http.StatusBadRequest, "message": err})
return
} else if resource.ID == 0 {
c.JSON(http.StatusNotFound, gin.H{"status": http.StatusNotFound, "message": "Resource with id:"+id+" does not exist"})
return
}
c.JSON(http.StatusOK, gin.H{
"id": resource.ID,
"data1": resource.Data1,
"data2": resource.Data2,
})
}
C.JSONが適切なhttp
ステータスとその他のデータを返していることをテストしたいと思います。 id
変数、err
変数、c.JSON
関数をモックする必要がありますが、テストでc.JSON
関数を新しい関数に設定しようとすると、 「Cannot assign to c.JSON
」というエラーが表示されます。以下はテストを書くための私の試みです:
resourceController_test.go
package controllers
import (
"github.com/gin-gonic/gin"
"github.com/stretchr/testify/assert"
"net/http/httptest"
"testing"
)
func TestGetResourceById(t *testing.T) {
var status int
var body interface{}
c, _ := gin.CreateTestContext(httptest.NewRecorder())
c.JSON = func(stat int, object interface{}) {
status = stat
body = object
}
GetResourceById(c)
assert.Equal(t, 4, 4)
}
ユニットテストを適切に記述して、c.JSONが適切な値を返すかどうかをテストするにはどうすればよいですか?
Goでタイプのメソッドを変更することはできません。コンパイル時に型を定義するパッケージによって定義され、変更できません。これはGoによる設計上の決定です。単にそれをしないでください。
_gin.Context.ResponseWriter
_の呼び出しを含め、応答に書き込まれた内容を記録する_c.JSON
_のモックとしてhttptest.NewRecorder()
をすでに使用しています。ただし、_httptest.ReponseRecorder
_の参照を保持して、後で確認する必要があります。マーシャリングされたJSONしかないので、コンテンツを確認するためにアンマーシャリングする必要があることに注意してください(GoマップとJSONオブジェクトの順序の両方が重要ではないため、マーシャリングされた文字列が等しいかどうかを確認するとエラーが発生しやすくなります)。
例えば、
_func TestGetResourceById(t *testing.T) {
w := httptest.NewRecorder()
c, _ := gin.CreateTestContext(w)
GetResourceById(c)
assert.Equal(t, 200, w.Code) // or what value you need it to be
var got gin.H
err := json.Unmarshal(&got, w.Body().Bytes())
if err != nil {
t.Fatal(err)
}
assert.Equal(t, want, got) // want is a gin.H that contains the wanted map.
}
_