首页 >后端开发 >Golang >如何使用 Mocking 在 Golang 中有效地对 GraphQL 解析器进行单元测试?

如何使用 Mocking 在 Golang 中有效地对 GraphQL 解析器进行单元测试?

Linda Hamilton
Linda Hamilton原创
2024-10-26 14:39:31464浏览

How to Effectively Unit Test GraphQL Resolvers in Golang with Mocking?

Golang 中的 GraphQL 单元测试

简介

单元测试是编写健壮可靠的软件的一个重要方面。在 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>

测试 ValidateAccessToken 解析器

我们使用 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中文网其他相关文章!

声明:
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn