【RSpec】Active Hash를 이용한 카테고리로 테스트를 패스하는 방법

htps : // 놀라운 l. 코m/쿠에 s치온 s/275207
결론 이 기사

이번에는 active hash를 이용한 카테고리시에 테스트가 통과하는 문제를 해결해 나갈 것입니다.

자세히 말하면,

컨트롤러의 단위 테스트에서,
    it 'showアクションにリクエストすると,そのコーヒーの産地が表示' do
      get drink_path(@drink)
      expect(response.body).to include('マルチリージョン')
    end

이러한 테스트를 통과하지 못했습니다.

예상되는 동작으로는



이 이미지의 오른쪽 부분에,
「산지 멀티 리전」
그래서, 위와 같은 테스트를 작성했지만,
drinks/show.html.erb
                <% if @drink.region %>
                  <th class="region-title">産地 </th>
                   <td class="region-name"><%= @drink.region.name%> </td>             
                <% end %>

@drinks.region.name 에는 "멀티 리전"이라는 문자가 들어 싶었지만,

위의 테스트를 실행한 결과,
 Drinks GET #show showアクションにリクエストすると,そのコーヒーの産地が表示
     Failure/Error: expect(response.body).to include('マルチリージョン')

       expected "\n<!DOCTYPE html>\n<html>\n  <head>\n    <title>Details | Coffee Passport</title>\n    \n    \n\n   ...script src=\"/packs-test/js/footer-c1b52f0e268f9a453b2e.js\"></script>\n   \n  </body>\n</html>\n\n" to include "マルチリージョン"
       Diff:

中略

       +              <tr class="item-region">
       +                  <th class="region-title">産地 </th>
       +                   <td class="region-name"> </td>             
       +              </tr>


이러한 HTML이 반환되고,
<td class="region-name"> </td>
여기에 @drink.region.name이 들어야하지만,
아무것도 들어가지 않았기 때문에 여러 가지 시도했습니다.
여러가지 시험한 결과는, 「teratail에게 질문하려고 한 문장」의 부분에 여러가지 써 있습니다.

해당 코드



drinks/show.html.erb
   <% if @drink.region %>
     <th class="region-title">産地 </th>
     <td class="region-name"><%= @drink.region.name%> </td>             
    <% end %>

models/region.rb
class Region < ActiveHash::Base
  self.data = [
    { id: 1, name: '---'},
    { id: 2, name: 'マルチリージョン' },
    { id: 3, name: 'ラテンアメリカ' },
    { id: 4, name: 'アフリカ' },
    { id: 5, name: 'アジア、太平洋' }
  ]
end


factories/drinks.rb
FactoryBot.define do
  factory :drink do
    name                {"TOKYOロースト"}
    price               {350}
    explain             {"これはコーヒーの説明です"}
    region_id           {2}

이러한 active hash를 사용한 구성의 경우, <%= @drink.region.name%>
표시되어 있는지 확인하고 싶기 때문에,

spec/requests/drinks_spec.rb
    it 'showアクションにリクエストすると,そのコーヒーの産地が表示' do
      get drink_path(@drink)
      expect(response.body).to include('マルチリージョン')
    end

그리고 테스트를 썼다.

그러나 이것이라면 앞에서 설명한대로 잘 작동하지 않습니다.

spec/requests/drinks_spec.rb
require 'rails_helper'
# bundle exec rspec spec/requests/tweets_spec.rb

RSpec.describe "Drinks", type: :request do
  before do
    @user = FactoryBot.create(:user)
    region_id = Region.find_by(name: 'マルチリージョン').id
    body_id = Body.find_by(name: "LIGHT(軽い)").id
    acidity_id = Acidity.find_by(name: "LOW(少ない)").id
    processing_id = Processing.find_by(name: "WASHED(水洗式)").id
    @drink = FactoryBot.create(:drink,
                                name: "TOKYOロースト",
                                price: 350,
                                explain: "これはコーヒーの説明です",
                                region_id: region_id,
                                body_id: body_id,
                                acidity_id: acidity_id,
                                processing_id: processing_id)

결론 이렇게 쓰면 잘 된다

models/region.rb
class Region < ActiveHash::Base
  self.data = [
    { id: 1, name: '---'},
    { id: 2, name: 'マルチリージョン' },
    { id: 3, name: 'ラテンアメリカ' },
    { id: 4, name: 'アフリカ' },
    { id: 5, name: 'アジア、太平洋' }
  ]
end


spec/requests/drinks_spec.rb
    region_id = Region.find_by(name: 'マルチリージョン').id

    @drink = FactoryBot.create(:drink,
                                name: "TOKYOロースト",
                                price: 350,
                                explain: "これはコーヒーの説明です",
                                region_id: region_id,

이제 잘 얻을 수 있고 테스트를 통과 할 수 있습니다.

어쩌면 이것은 장황하고, 모범 사례가 아닌 것 같은 생각이 들기 때문에, 프로의 Rubist 여러분에게 의견을 묻고 싶기 때문에, 그것을 추기해 갑니다.

teratail에게 질문하려고 한 문장



이 앱의 github



일어나는 문제는 이것에 가깝습니다.



발생한 문제 및 오류 메시지


 Drinks GET #show showアクションにリクエストすると,そのコーヒーの産地が表示
     Failure/Error: expect(response.body).to include('マルチリージョン')

       expected "\n<!DOCTYPE html>\n<html>\n  <head>\n    <title>Details | Coffee Passport</title>\n    \n    \n\n   ...script src=\"/packs-test/js/footer-c1b52f0e268f9a453b2e.js\"></script>\n   \n  </body>\n</html>\n\n" to include "マルチリージョン"
       Diff:

中略

       +              <tr class="item-region">
       +                  <th class="region-title">産地 </th>
       +                   <td class="region-name"> </td>             
       +              </tr>

 <td class="region-name"> </td>   

여기에 커피의 지역이 표시되어야하지만 테스트에서 반환 된 HTML에는 표시되지 않으므로 테스트를 통과 할 수 없습니다.

원인은



이 이미지의, 이 투고의 산지 부분의 「멀티 리전」이라든지, 코쿠의 「LIGHT(가벼운)」의 부분등이, 잘 표시되어 있지 않습니다.

해당 소스 코드



drinks/show.html
<% if @drink.region %>
<th class="region-title">産地 </th>
<td class="region-name"><%= @drink.region.name%> </td>
<% end %>

그리고, 이런 식으로, drinks/show에서는,
해당 게시물의 출처 이름이 표시되는 사양입니다.

region.rb
class Region < ActiveHash::Base
  self.data = [
    { id: 1, name: '---'},
    { id: 2, name: 'マルチリージョン' },
    { id: 3, name: 'ラテンアメリカ' },
    { id: 4, name: 'アフリカ' },
    { id: 5, name: 'アジア、太平洋' }
  ]

end

여기서 Active Hash를 사용하는 것이 원인입니다.

drinks_spec.rb
    it 'showアクションにリクエストすると,そのコーヒーの産地が表示' do
      get drink_path(@drink)
      expect(response.body).to include('マルチリージョン')
    end

spec/factories/drinks.rb
FactoryBot.define do
  factory :drink do
    name                {"TOKYOロースト"}
    price               {350}
    explain             {"これはコーヒーの説明です"}
    region_id           {Region.all.sample}
    body_id             {Body.all.sample}
    acidity_id          {Acidity.all.sample}
    processing_id       {Processing.all.sample}
    likes_count         {2}
    association :user 
    association :region
    association :body
    association :acidity
    association :processing

    after(:build) do |drink|
      drink.image.attach(io: File.open('app/assets/images/ethiopia.jpg'), filename: 'ethiopia.jpg')
    end
  end
end


spec/factories/regions.rb
FactoryBot.define do
  factory :region do
  end
end


시도한 것





이 두 기사를 참고하여

우선, factorybot끼리 어소시에이션을 짜지 않기 때문에, @drink.region.name이 표시되지 않는다고 생각해,

spec/factories/regions.rb
FactoryBot.define do
  factory :region do
    association :drink
  end
end


라고 쓰면

죽을수록 긴 오류가 표시되고 SystemStackError stack level too deep
이런 느낌의 오류가 나왔습니다.

다음

app/models/region.rb
class Region < ActiveHash::Base
  self.data = [
    { id: 1, name: '---'},
    { id: 2, name: 'マルチリージョン' },
    { id: 3, name: 'ラテンアメリカ' },
    { id: 4, name: 'アフリカ' },
    { id: 5, name: 'アジア、太平洋' }
  ]
  + include ActiveHash::Associations
   + has_many :drink
end


이런 식으로 작성했습니다.
첫 번째 오류와 다르지 않았습니다.

factories/region.rb
FactoryBot.define do
  factory :region do
    2      {'マルチリージョン'}
  end
end


이렇게 쓰면
SyntaxError:
  /coffee_passport/spec/factories/regions.rb:3: syntax error, unexpected '{', expecting end
      2      {'マルチリージョン'}
             ^

이런 오류가 발생했습니다.

factores/drinks.rb

    region_id           {Region.second}

이렇게 다시 작성하면
      Failure/Error: region_id           {Region.second}

      NoMethodError:
        undefined method `second' for Region:Class
        Did you mean?  send

그리고 오류가 나타났습니다.

좋은 웹페이지 즐겨찾기