GraphQL的各种测试

首先

我最近在使用Graphql-ruby实现API。
当然,我需要编写graphql测试,因为有很多不同的方法,所以我将它们总结在备忘录中。

实际上调用API的方法

首先,我会解释如何实际调用API。
以下是一个示例。

RSpec.describe User, type: :request do
  describe 'user' do
    it '指定したusrが取得できること' do
      user = create(:user)

      post '/graphql', params: { query: query(id: user.id) }
      json = JSON.parse(response.body)
      data = json['data']['user']

      expect(data).to include(
        'id' => user.id
      )
      end
    end
  end

  def query(id:)
    <<~GRAPHQL
      query {
        user(id: "#{id}"){
          id
          name
        }
      }
   GRAPHQL
  end
end

用中文将以下内容进行改述:
这是一个较为朴素的实现,即通过实际定义查询并将其发送到本地的API进行POST操作。
然而,这种方法存在一些麻烦之处,具体如下:

    • expectするためにいちいちパースとかjson形式で確認するのは面倒

 

    • contextを指定できない(current_userが指定できない)

 

    query書くの面倒

执行execute的方法

接下来是直接调用execute的方法。
这里先从例子开始。

RSpec.describe User, type: :request do
  describe 'user' do
    it '指定したusrが取得できること' do
      user = create(:user)
      
      # AppSchemaは定義されているスキーマ名に変えてください
      ret = AppSchema.execute(query(id: user.id) context:{current_user: user})
      data = ret['data']['user']

      expect(data).to include(
        'id' => user.id
      )
      end
    end
  end

  def query(id:)
    <<~GRAPHQL
      query {
        user(id: "#{id}"){
          id
          name
        }
      }
   GRAPHQL
  end
end

通过将JSON解析和响应传递给它,代码变得更简洁了,让人感觉舒畅了一些。
另外,由于可以传递上下文参数,测试变得更容易了。
然而,编写查询或从JSON格式中提取id这样的东西会变得很麻烦。
特别是当查询变得复杂且嵌套层级很深时,JSON格式就变得相当不方便。

只敲打解析器的方法

那么,让我们马上来看一个例子吧。

RSpec.describe User, type: :request do
  describe 'resolver' do
    it 'userが取得できること' do
      user = create(:user)

     # class_nameはロジックが書かれてるresolveのクラス名
      mutation = [class_name].new(field: nil, object: nil, context:{current_user: user})
      ret = mutation.resolve(id: user.id)
      expect(ret).to eq user
    end
  end
end

我已经解决了很多问题。
您可以看到,我使用了resolve类的实例,直接调用了resolve方法。使用这种方法,返回值将是一个user对象,这样测试就非常容易编写了。

你要用哪一个?

在测试与ObjectType等前端接口进行交互时,我直接调用execute方法来进行测试,而在测试其他逻辑时,我直接调用resolver方法。我很少使用直接调用第一个api的方法。

我将我所知道的测试方法总结在上面。如果有其他好的方法,希望能在评论中告诉我,我会很高兴的。

广告
将在 10 秒后关闭
bannerAds