90621


# やりたいこと

RailsアプリでRSpecを使ってリクエストテストを行っています。  
`User`に関連する子データとして`Post`があり、それぞれFactoryBotを使ってファクトリーを作っていて、リクエストテストで`POSTメソッド`を明示的に使用して新規`Post`レコードを作成したときのレコード数の変化と、リダイレクトされたHTTPステータスのテストを行いたいです。  
また、`User`モデルはdeviseで自動生成されたモデルを使っています。

# モデル

##### app/models/user.rb

[code]

    class User < ApplicationRecord
      devise :database_authenticatable, :registerable,
             :recoverable, :rememberable, :validatable
    
      has_many :posts
    end
    
[/code]

##### app/models/post.rb

[code]

    class Post < ApplicationRecord
      belongs_to :user
    end
    
[/code]

# 各モデルのFactoryのソース

##### spec/factories/users.rb

[code]

    FactoryBot.define do
      factory :user do
        email { "test@example.com" }
        password { "123456" }
        password_confirmation { "123456" }
        name { "Test" }
      end
    end
    
[/code]

##### spec/factories/posts.rb

[code]

    FactoryBot.define do
      factory :post do
        date { Date.new.strftime("%Y-%m-%d") }
        start_time { Time.new.strftime("%H:%M") }
        end_time { Time.new.strftime("%H:%M") }
        kind_of_climbing { 0 }
        sequence(:describe) { |n| "test test#{n}" }
      end
    end
    
[/code]

# Postのリクエストスペック

##### spec/requests/posts_spec.rb

[code]

    require 'rails_helper'
    
    RSpec.describe "/posts", type: :request do
      
      let(:valid_attributes) {
        {
          date: Date.new.strftime("%Y-%m-%d"),
          start_time: Time.new.strftime("%H:%M"),
          end_time: Time.new.strftime("%H:%M"),
          kind_of_climbing: 0,
          describe: 'test test'
        }
      }
    
      let(:user) { FactoryBot.create(:user) }
    
      before do
        sign_in user
        @post = FactoryBot.create(:post, user_id: user.id)
      end
    
      describe "POST /create" do
        context "with valid parameters" do
          it "creates a new Post" do
            expect {
              post posts_url, params: { post: valid_attributes }
            }.to change(Post, :count).by(1)
          end
    
          it "redirects to the created post" do
            post posts_url, params: { post: valid_attributes }
            expect(response).to redirect_to(post_url(Post.last))
          end
        end
      end
    
    end
    
[/code]

# 質問内容

上記のリクエストスペックで、最初にletで`user`という変数に入れたオブジェクトに関連する`Post`をPOSTメソッドで作成するようにしたいのですが、どのようにすれば良いでしょうか？

# 試したこと

##### spec/requests/posts_spec.rb

[code]

    it "creates a new Post" do
      expect {
        # post posts_url, params: { post: valid_attributes }
        user.posts.create( valid_attributes )
      }.to change(Post, :count).by(1)
    end
    
[/code]

とすることで、`Post`に新規レコードを作成し、カウントを1つ上げるテストをすることはできたのですが、これだとPOSTメソッドのURLに投げていないので、その後のリダイレクトをテストすることができませんでした。

よろしくお願いいたします。


CC BY-SA 4.0
2021-10-28T01:01:06.370
83289
2022-08-18T16:48:19.810
192
question
ruby-on-rails rspec
RSpecでFactoryBotを使い、POSTメソッドに関するリクエストSpecを書くのはどうすれば良いか？


テストの問題というよりも実装の修正が必要かなと思いました  
ログインが必要なアプリケーションであればposts#createでログインユーザーに紐づくpostを作成するように実装されていれば

`post posts_url, params: { post: valid_attributes }`  
でログイユーザー（この場合は `user`）に紐づくpostが作成されます


CC BY-SA 4.0
2022-08-18T16:48:19.810
90621
2022-08-18T16:48:19.810
54050
83289
answer