在 Golang 中对 GraphQL 进行单元测试 [英] unit testing GraphQL in Golang
本文介绍了在 Golang 中对 GraphQL 进行单元测试的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
在这种情况下我使用
- 回声
- mongo-driver (MongoDB)
- gqlgen
源代码:https://github.com/mrdulin/gqlgen-cnode>
in this case I am using
- Echo
- mongo-driver (MongoDB)
- gqlgen graphql type safe
is there any simple example for testing my Mutation and Query ? I do love to get advices for this. I have tried to find but can't found any so far,
thank you :)
解决方案Here is an test example using testify package and the gqlgen/client package which is used internally for testing.
GraphQL schema:
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
:package resolver import "github.com/mrdulin/gqlgen-cnode/services" // This file will not be regenerated automatically. // // It serves as dependency injection for your app, add any dependencies you require here. type Resolver struct { UserService services.UserService }
services/user.go
:package services type UserService interface { GetUserByLoginname(loginname string) *model.UserDetail ValidateAccessToken(accesstoken string) *model.UserEntity }
graph/resolver/root.resolver.go
:package resolver // This file will be automatically regenerated based on the schema, any resolver implementations // will be copied through when generating and any unknown code will be moved to the end. 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 &mutationResolver{r} } // Query returns generated.QueryResolver implementation. func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } type mutationResolver struct{ *Resolver } type queryResolver struct{ *Resolver }
Created mock object for
UserService
:mocks/userService.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) }
graph/resolver/root.resolver_test.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: &resolvers}))) ue := model.UserEntity{ID: "123", User: model.User{Loginname: &loginname, AvatarURL: &avatarURL}} testUserService.On("ValidateAccessToken", mock.AnythingOfType("string")).Return(&ue) var resp struct { ValidateAccessToken struct{ ID, Loginname, AvatarUrl string } } q := ` mutation { validateAccessToken(accesstoken: "abc") { id, loginname, avatarUrl } } ` c.MustPost(q, &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: &resolvers}))) u := model.UserDetail{User: model.User{Loginname: &loginname, AvatarURL: &avatarURL}, Score: &score, CreateAt: &createAt} testUserService.On("GetUserByLoginname", mock.AnythingOfType("string")).Return(&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, &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) }) }
test result:
=== RUN TestMutationResolver_ValidateAccessToken === RUN TestMutationResolver_ValidateAccessToken/should_validate_accesstoken_correctly TestMutationResolver_ValidateAccessToken/should_validate_accesstoken_correctly: root.resolvers_test.go:44: PASS: ValidateAccessToken(mock.AnythingOfTypeArgument) --- PASS: TestMutationResolver_ValidateAccessToken (0.00s) --- PASS: TestMutationResolver_ValidateAccessToken/should_validate_accesstoken_correctly (0.00s) === RUN TestQueryResolver_User === RUN TestQueryResolver_User/should_query_user_correctly --- PASS: TestQueryResolver_User (0.00s) --- PASS: TestQueryResolver_User/should_query_user_correctly (0.00s) PASS ok github.com/mrdulin/gqlgen-cnode/graph/resolver 0.141s
test coverage report:
source code: https://github.com/mrdulin/gqlgen-cnode
这篇关于在 Golang 中对 GraphQL 进行单元测试的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文