もふもふ技術部

IT技術系mofmofメディア

graphql-rubyでRSpec実装してみた

はじめに

graphql-rubyでは大きく分けてスキーマ構造テストと統合テストの2種類がありますが、今回は統合テストのmutationスペックについて紹介していきます。

記事について

graphql-ruby初学者向けの記事を書いています。

関連記事

  1. graphql-batchでN+1を解消してみた
  2. 無限ページネーション
  3. 個人開発のcodegen.ymlの設定について考えてみた
  4. ファイルアップロード機能を実装してみた
  5. graphql-rubyRSpec実装してみた(現在の記事)

使用技術

ruby 3.1.2
rails 7.0.3.1
graphql 2.0.13

mutationスペック

user新規登録のmutationスペックを実装してみます。

module Mutations
  class SignUp < Mutations::BaseMutation
    argument :params, InputTypes::User, required: true

    field :user, ObjectTypes::User, null: false

    def resolve(params:)
      user = User.create(params.to_h)
      { user: }
    end
  end
end
require 'rails_helper'

RSpec.describe Mutations::SignUp do
  describe 'user作成' do
    it 'userが作成されていること' do
      query_string = <<-GRAPHQL
        mutation signUp($name: String! = "test_name", $email: String! = "test@example.com", $password: String! = "password", $passwordConfirmation: String! = "password") {
          signUp(input: {params: {name: $name, email: $email, password: $password, passwordConfirmation: $passwordConfirmation}}) {
            user {
              id
              name
              email
            }
          }
        }
      GRAPHQL
      result = MyappSchema.execute(query_string)
      expect(result.dig('data', 'signUp', 'user')).not_to be_blank
      user = User.find_by(email: 'test@example.com')
      expect(user.present?).to be true
    end
  end
end

ここで、同じmutationを使い回すような時、queryをメソッド化することもできます。

RSpec.describe Mutations::SignUp do
  describe 'user作成' do
    it 'userが作成されていること' do
      result = MyappSchema.execute(
        sign_up_query, variables: {
          name: 'test_name',
          email: 'test@example.com',
          password: 'password',
          passwordConfirmation: 'password'
        }
      )
      expect(result.dig('data', 'signUp', 'user')).not_to be_blank
      user = User.find_by(email: 'test@example.com')
      expect(user).to be_present
    end
  end

  def sign_up_query
    <<-GRAPHQL
      mutation SignUp($name: String!, $email: String!, $password: String!, $passwordConfirmation: String!) {
        signUp(input: {params:{name: $name, email: $email, password: $password, passwordConfirmation: $passwordConfirmation}}) {
          user {
            id
            name
            email
          }
        }
      }
    GRAPHQL
  end
end

失敗時のテストはこんな感じです。

it 'nameが空白だとエラーが発生すること' do
  result = MyappSchema.execute(
    sign_up_query, variables: {
      name: '',
      email: 'test@example.com',
      password: 'password',
      passwordConfirmation: 'password'
    }
  )
  expect(result['errors'].first['message']).to eq("Name can't be blank")
end

contextを使用する場合

Todoアプリでtaskを作成する時のテストを実装します。 userとtaskで1対多のアソシエーションでの想定です。

module Mutations
  class CreateTask < Mutations::BaseMutation
    argument :params, InputTypes::Task, required: true

    field :task, ObjectTypes::Task, null: false

    def resolve(params:)
      context[:current_user].tasks.create(params.to_h)
    end
  end
end
require 'rails_helper'

RSpec.describe Mutations::CreateTask do
  describe 'user作成' do
    let!(:user) { create(:user) }

    it 'taskが作成されていること' do
      result = MyappSchema.execute(
        create_task_query,
        variables: {
          title: 'テストタイトル',
          body: 'テストボディ'
        },
        context: { current_user: user }
      )
      expect(result.dig('data', 'createTask', 'task')).not_to be_blank
    end
  end

  def create_task_query
    <<-GRAPHQL
      mutation createTask($title: String!, $body: String!) {
        createTask(input: { params: { title: $title, body: $body } }) {
          task {
            id
            title
            body
          }
        }
      }
    GRAPHQL
  end
end

さいごに

今回でgraphql-rubyでのRSpecに慣れることができました。 graphql-ruby入門者の方の参考になれば幸いです。

参考

https://www.marsa-blog.com/2020/08/rails-graphql-test.html

会社の紹介

株式会社 mofmof では一緒に働いてくれるエンジニアを募集しています。 興味のある方は是非こちらのページよりお越しください! https://www.mof-mof.co.jp/ https://www.mof-mof.co.jp/recruit/