单元测试是编写健壮可靠的软件的一个重要方面。在 Golang 中使用 GraphQL 时,必须测试查询和突变解析器,以确保它们的行为符合预期。
测试 GraphQL 解析器的关键挑战之一是它们通常依赖外部服务,例如数据库或 API。为了防止这些依赖项干扰我们的测试,我们可以使用模拟。模拟允许我们创建模仿真实服务行为的假对象。
让我们考虑一个要测试 User 和 ValidateAccessToken 解析器的示例。我们定义一个代表真实服务的 UserService 接口,然后我们实现一个模拟实现以用于测试目的。
<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>
接下来,我们通过创建一个新的来设置我们的测试具有模拟服务的解析器:
<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" )</code>
我们使用 gqlgen/client 包针对我们的模拟服务执行 GraphQL 查询和突变。
<code class="go">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) }) }</code>
类似地,我们可以测试用户解析器:
<code class="go">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") }) }</code>
Golang 中的 GraphQL 解析器单元测试涉及使用模拟来隔离解析器免受外部依赖,使您可以专注于测试其功能。通过遵循本指南中概述的步骤,您可以确保解析器按预期运行并提供一致且可靠的 GraphQL API。
以上是如何使用 Mocking 在 Golang 中有效地对 GraphQL 解析器进行单元测试?的详细内容。更多信息请关注PHP中文网其他相关文章!