Testify と gqlgen/client を使用して Go で GraphQL リゾルバーを単体テストする方法

Patricia Arquette
リリース: 2024-10-28 05:00:01
オリジナル
560 人が閲覧しました

How to Unit Test GraphQL Resolvers in Go with Testify and gqlgen/client?

testify を使用した Go での GraphQL の単体テスト

GraphQL スキーマでは、Query 構造体はデータの取得をトリガーする操作と Mutation 構造体を定義します。状態を変更する操作を定義します。テストするときは、実際の CRUD 操作を実行するオブジェクトをモックし、予期した呼び出しが行われたことをアサートする必要があります。

次の例では、testify パッケージと gqlgen/client パッケージを使用します。

graph/schema.graphql

type Query {
  user(loginname: String!): UserDetail
}

type Mutation {
  validateAccessToken(accesstoken: String!): UserEntity
}

type User { 
  loginname: String 
  avatarUrl: String 
}

type UserEntity {
  id: ID!
  loginname: String 
  avatarUrl: String
}

type UserDetail { 
  loginname: String
  avatarUrl: String
  githubUsername: String
  createAt: String
  score: Int
}
ログイン後にコピー

graph/resolver/resolver.go

<code class="go">package resolver

import (
    "github.com/mrdulin/gqlgen-cnode/services"
)

type Resolver struct {
    UserService    services.UserService
}</code>
ログイン後にコピー

services/user.go

<code class="go">package services

type UserService interface {
    GetUserByLoginname(loginname string) *model.UserDetail
    ValidateAccessToken(accesstoken string) *model.UserEntity
}</code>
ログイン後にコピー

graph/resolver/root.resolver.go

<code class="go">package resolver

import (
    "context"

    "github.com/mrdulin/gqlgen-cnode/graph/generated"
    "github.com/mrdulin/gqlgen-cnode/graph/model"
)

func (r *mutationResolver) ValidateAccessToken(ctx context.Context, accesstoken string) (*model.UserEntity, error) {
    return r.UserService.ValidateAccessToken(accesstoken), nil
}

func (r *queryResolver) User(ctx context.Context, loginname string) (*model.UserDetail, error) {
    return r.UserService.GetUserByLoginname(loginname), nil
}

// Mutation returns generated.MutationResolver implementation.
func (r *Resolver) Mutation() generated.MutationResolver { return &amp;mutationResolver{r} }

// Query returns generated.QueryResolver implementation.
func (r *Resolver) Query() generated.QueryResolver { return &amp;queryResolver{r} }

type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }</code>
ログイン後にコピー

GraphQL リクエストとレスポンスをシミュレートするには、次のようにします。サービスのモック オブジェクトを作成できます:

mocks/userService.go

<code class="go">package mocks

import (
    "github.com/mrdulin/gqlgen-cnode/graph/model"
    "github.com/stretchr/testify/mock"
)

type MockedUserService struct {
    mock.Mock
}

func (s *MockedUserService) GetUserByLoginname(loginname string) *model.UserDetail {
    args := s.Called(loginname)
    return args.Get(0).(*model.UserDetail)
}

func (s *MockedUserService) ValidateAccessToken(accesstoken string) *model.UserEntity {
    args := s.Called(accesstoken)
    return args.Get(0).(*model.UserEntity)
}</code>
ログイン後にコピー

最後に、テスト ファイルでこれらのモックをインポートし、次の目的で使用できます。 GraphQL リゾルバーをテストします:

graph/resolver/root.resolver_test.go

<code class="go">package resolver_test

import (
    "testing"

    "github.com/99designs/gqlgen/client"
    "github.com/99designs/gqlgen/graphql/handler"
    "github.com/mrdulin/gqlgen-cnode/graph/generated"
    "github.com/mrdulin/gqlgen-cnode/graph/model"
    "github.com/mrdulin/gqlgen-cnode/graph/resolver"
    "github.com/mrdulin/gqlgen-cnode/mocks"
    "github.com/stretchr/testify/mock"
    "github.com/stretchr/testify/require"
)

var (
    loginname = "mrdulin"
    avatarURL = "avatar.jpg"
    score     = 50
    createAt  = "1900-01-01"
)

func TestMutationResolver_ValidateAccessToken(t *testing.T) {

    t.Run("should validate accesstoken correctly", func(t *testing.T) {
        testUserService := new(mocks.MockedUserService)
        resolvers := resolver.Resolver{UserService: testUserService}
        c := client.New(handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &amp;resolvers})))
        ue := model.UserEntity{ID: "123", User: model.User{Loginname: &amp;loginname, AvatarURL: &amp;avatarURL}}
        testUserService.On("ValidateAccessToken", mock.AnythingOfType("string")).Return(&amp;ue)
        var resp struct {
            ValidateAccessToken struct{ ID, Loginname, AvatarUrl string }
        }
        q := `
      mutation { 
        validateAccessToken(accesstoken: "abc") { 
          id, 
          loginname, 
          avatarUrl 
        } 
      }
    `
        c.MustPost(q, &amp;resp)
        testUserService.AssertExpectations(t)
        require.Equal(t, "123", resp.ValidateAccessToken.ID)
        require.Equal(t, "mrdulin", resp.ValidateAccessToken.Loginname)
        require.Equal(t, "avatar.jpg", resp.ValidateAccessToken.AvatarUrl)
    })

}

func TestQueryResolver_User(t *testing.T) {
    t.Run("should query user correctly", func(t *testing.T) {
        testUserService := new(mocks.MockedUserService)
        resolvers := resolver.Resolver{UserService: testUserService}
        c := client.New(handler.NewDefaultServer(generated.NewExecutableSchema(generated.Config{Resolvers: &amp;resolvers})))
        u := model.UserDetail{User: model.User{Loginname: &amp;loginname, AvatarURL: &amp;avatarURL}, Score: &amp;score, CreateAt: &amp;createAt}
        testUserService.On("GetUserByLoginname", mock.AnythingOfType("string")).Return(&amp;u)
        var resp struct {
            User struct {
                Loginname, AvatarURL, CreateAt string
                Score                          int
            }
        }
        q := `
      query GetUser($loginname: String!) { 
        user(loginname: $loginname) { 
          loginname
          avatarUrl 
          createAt 
          score 
        } 
      }
    `
        c.MustPost(q, &amp;resp, client.Var("loginname", "mrdulin"))
        testUserService.AssertCalled(t, "GetUserByLoginname", "mrdulin")
        require.Equal(t, "mrdulin", resp.User.Loginname)
        require.Equal(t, "avatar.jpg", resp.User.AvatarURL)
        require.Equal(t, 50, resp.User.Score)
        require.Equal(t, "1900-01-01", resp.User.CreateAt)
    })
}</code>
ログイン後にコピー

このテストは、サービス メソッドに対して正しい呼び出しが行われていることを確認します。 、応答が期待どおりにフォーマットされていることを確認します。テスト カバレッジ レポートには、リゾルバー機能の完全なカバレッジが表示される必要があります。

以上がTestify と gqlgen/client を使用して Go で GraphQL リゾルバーを単体テストする方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
著者別の最新記事
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!