在这种情况下,我正在使用
- 回声
- mongo驱动程序(MongoDB)
- gqlgen graphql 类型安全
有什么简单的例子可以测试我的 Mutation 和 Query 吗?我很乐意为此获得建议。我试图找到,但到目前为止找不到任何东西,
谢谢你 :)
在这种情况下,我正在使用
有什么简单的例子可以测试我的 Mutation 和 Query 吗?我很乐意为此获得建议。我试图找到,但到目前为止找不到任何东西,
谢谢你 :)
这是一个使用testify包和内部用于测试的gqlgen/client包的测试示例。
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
:
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 }
为:创建模拟对象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)
})
}
测试结果:
=== 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
测试覆盖率报告: