Computer >> 컴퓨터 >  >> 프로그램 작성 >> Ruby

ViewComponent Gem 소개

React에서 영감을 받은 ViewComponent는 뷰를 렌더링하기 위한 마크업을 빌드하는 데 사용되는 Ruby 객체입니다. ViewComponent는 Rails에서 재사용 가능하고 테스트 가능하며 캡슐화된 뷰 구성 요소를 빌드하기 위한 프레임워크입니다. 일반적으로 재사용 가능한 뷰는 부분을 사용하여 Rails에서 생성된 다음 필요에 따라 다른 뷰에서 렌더링되지만 ViewComponent gem이 도입되면서 부분이 더 많은 이점을 제공하므로 부분을 뷰 구성 요소로 교체할 수 있습니다. 이러한 장점이 무엇인지 자세히 알아보겠습니다.

ViewComponents는 언제, 왜 사용해야 하나요?

앞에서 언급했듯이 뷰 구성 요소는 재사용 및 테스트가 가능합니다. 따라서 뷰를 재사용하거나 직접 테스트하여 이점을 얻을 때마다 적용할 수 있습니다. 설명서에 명시된 대로 보기 구성 요소의 이점 중 일부는 다음과 같습니다.

  • 파셜보다 최대 10배 빠릅니다.
  • 루비 객체입니다. 따라서 그들의 initialize 메소드는 뷰를 렌더링하는 데 필요한 것을 명확하게 정의합니다. 이는 다른 여러 보기에서 더 쉽게 이해하고 재사용할 수 있음을 의미합니다. 또한 Ruby 코드의 품질 표준을 적용할 수 있으므로 버그 위험을 줄일 수 있습니다.
  • Rails의 기존 보기와 달리 단위 테스트가 가능하며, 보기 외에 라우팅 및 컨트롤러 레이어도 실행하는 통합 테스트가 필요합니다.

ViewComponent 구현

ViewComponent는 ViewComponent::Base의 하위 클래스입니다. app/components에 살고 있습니다. . 이름은 - Component로 끝납니다. , 그리고 그것들은 그들이 받아들이는 것이 아니라 그들이 렌더링하는 것에 대한 이름을 지어야 합니다. 수동으로 또는 구성 요소 생성기를 통해 보기 구성 요소를 생성할 수 있지만 gemfile에 gem을 추가하고 bundle install를 실행하지 않고는 생성할 수 없습니다. 먼저.

gem "view_component", require: "view_component/engine"

생성기를 사용하려면 다음 명령을 실행하십시오.

rails generate component <Component name> <arguments needed for initialization>

예를 들어 학습 플랫폼에서 사용할 수 있는 강의 목록을 표시하는 구성 요소를 생성하려는 경우 다음 명령을 사용할 수 있습니다.

rails g component Course course

course을 통과합니다. 이 Ruby 객체를 표시할 것으로 예상하는 과정으로 초기화하고 이름을 Course로 지정했기 때문에 명령에 대한 인수 코스를 렌더링하기 때문입니다. 우연의 일치입니다!

ViewComponent Gem 소개

위에서 볼 수 있듯이 구성 요소와 해당 보기는 app/components 폴더, 테스트 파일과 함께.

ViewComponent에는 erb용 템플릿 생성기가 포함되어 있습니다. , haml , 및 slim 템플릿 엔진이지만 기본적으로 config.generators.template_engine에 지정된 템플릿 엔진으로 설정됩니다. .그래도 다음을 사용하여 선호하는 템플릿 엔진을 지정할 수 있습니다.

rails generate component Course course --template-engine <your template engine>

계속해서 코스 모델을 만들고 표시할 몇 가지 코스를 만들어 보겠습니다.

rails g model Course title:string price:decimal location:string
rails db:migrate

콘솔에서 두 개의 새 과정을 빠르게 만들 수 있습니다.

Course.create(title: 'The Art of Learning', price: 125.00, location: 'Denmark')
Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')

course_component.rb 아래와 같이 initialize 메소드를 사용하여 파일이 생성됩니다.

ViewComponent Gem 소개

코스 목록으로 연결하는 코스 컨트롤러를 만들어야 합니다.

rails g controller Courses index

routes.rb에서 파일에 다음을 추가하여 루트 경로를 나타냅니다.

root 'courses#index'

이제 모든 설정이 완료되었으므로 다음 단계는 뷰 생성입니다. 이것은 이미 생성된 course_component.html.erb에서 수행됩니다. .

<div>
  <h2><%= @course.title %></h2>
  <h4><%=  number_to_currency(@course.price, :unit => "€") %></h4>
  <h4><%= @course.location %></h4>
</div>

우리 보기에서는 @course를 사용하여 과정 제목, 가격 및 위치를 표시합니다. CourseComponent의 initialize 메소드에 이미 정의된 변수입니다. 이는 컨트롤러 메소드에서 변수를 생성한 다음 뷰에서 사용할 수 있는 것과 유사합니다.

컨트롤러가 어떻게 작동하는지 알면 해당 index.html.erb로 라우팅됩니다. 우리의 인덱스 방법의. 따라서 여기에서 구성 요소를 렌더링합니다.

#app/views/courses/index.html.erb
<%= render(CourseComponent.new(course: Course.find(1))) %>

위에서 본 것처럼 CourseComponent를 뷰에서 렌더링하려는 과정으로 초기화하여 CourseComponent의 새 인스턴스를 렌더링합니다. 이 과정은 @course가 됩니다. course_component.html.erb에서 사용할 수 있는 변수 파일.

또한 이 구성 요소를 컨트롤러에서 직접 렌더링하여 인덱스 파일 보기를 우회할 수도 있습니다.

class CoursesController < ApplicationController
  def index
    render(CourseComponent.new(course: Course.find(1)))
  end
end

어떤 방법을 선택하든 서버에 다음과 같이 표시됩니다.

ViewComponent Gem 소개

다음 방법 중 하나로 추가 콘텐츠를 구성 요소에 전달할 수도 있습니다.

<%= render(CourseComponent.new(course: Course.find(1))) do %>
  container
<% end %>
<%= render(CourseComponent.new(course: Course.find(1)).with_content("container")) %>

보기 구성 요소 파일에서 원하는 곳에 내용을 포함할 수 있습니다. 이 경우 div를 다음과 같이 편집하여 클래스로 포함합니다.

<div class=<%= content %>>

추가 콘텐츠를 렌더링하는 위의 모든 방법은 아래 이미지를 생성합니다.

ViewComponent Gem 소개

컬렉션 렌더링

전체 과정 목록을 렌더링하려면 어떻게 해야 합니까? ViewComponent는 with_collection을 사용하여 이를 수행하는 매우 간단한 방법을 제공합니다. 꼬리표. .new를 사용하여 구성요소를 초기화하는 대신 , .with_collection을 사용하여 초기화됩니다. , 그리고 컬렉션은 아래와 같이 변수로 전달됩니다.

CourseComponent.with_collection(Course.all)

결과는 다음과 같습니다.

ViewComponent Gem 소개

with_collection_parameter도 있습니다. 컬렉션의 주소를 다른 이름으로 지정하려는 경우에 사용할 수 있는 태그입니다.

class CourseComponent < ViewComponent::Base
  with_collection_parameter :item

  def initialize(item:)
    @item = item
  end
end

위의 경우 코스 매개변수는 item으로 지정되었습니다. . 따라서 해당 보기에서 @course @item으로 대체됩니다. 동일한 결과를 얻을 수 있습니다.

컬렉션에 추가 매개변수를 추가할 수도 있습니다. 이 매개변수는 컬렉션의 항목별로 표시됩니다. Buy Me를 추가해 보겠습니다. 이 방법을 통해 각 항목에 텍스트를 보냅니다.

#app/views/courses/index.html.erb
<%= render(CourseComponent.with_collection(Course.all, notice: "Buy Me")) %>
# app/components/course_component.rb
class CourseComponent < ViewComponent::Base
  with_collection_parameter :item
  def initialize(item:, notice:)
    @item = item
    @notice = notice
  end
end

app/components/course_component.html.erb에 새 단락을 추가합니다. 새로 추가된 알림 변수에 대한 텍스트를 나타내는 파일입니다.

<p><a href='#'> <%= @notice %> </a></p>

결과는 다음과 같습니다.

ViewComponent Gem 소개

마지막으로 컬렉션 아래에는 보기의 항목에 번호를 매길 수 있는 카운터 변수가 있습니다. _counter를 추가하면 활성화됩니다. 컬렉션 매개변수에 추가하고 initialize 메소드를 통해 뷰에서 사용할 수 있도록 합니다.

#app/components/course_component.rb
def initialize(item:, notice:, item_counter:)
  @item = item
  @notice = notice
  @counter = item_counter
end

보기에서 항목 제목 옆에 카운터를 추가합니다.

<h2><%= @counter %>. <%= @item.title %></h2>

카운터 현상을 더 잘 이해하기 위해 콘솔에서 세 번째 과정을 생성해 보겠습니다.

Course.create(title: 'Understanding Databases', price: '100', location: 'Amsterdam')

이것은 다음을 산출합니다

ViewComponent Gem 소개

조건부 렌더링

ViewComponent에 render?가 있습니다. 후크는 사용 시 뷰를 렌더링해야 하는지 여부를 결정합니다. 이를 구현하기 위해 가격이 100유로 이상인 코스에 대해 10% 할인을 제공합니다. 이를 위한 구성 요소를 만들어 보겠습니다.

rails generate component Discount item

ViewComponent Gem 소개

이 구성 요소는 아래와 같이 할인을 표시해야 하는 항목으로 이미 자동으로 초기화됩니다.

ViewComponent Gem 소개

따라서 discount_component.html.erb에서 파일에 표시하려는 텍스트를 추가합니다.

<p class="green"> A 10% discount is available on this course </p>

주저하지 말고 green 클래스를 추가하세요. css 파일에 추가하고 원하는 녹색 음영을 지정합니다. 또한 discount_component.rb에서 파일에 render?를 추가합니다. 이 구성 요소를 렌더링해야 하는 시기를 결정하는 메서드입니다.

def render?
  @item.price >= 100
end

이제 각 과정을 렌더링하는 보기 내에서 할인 구성 요소를 렌더링할 수 있습니다.

# app/components/course_component.html.erb
<%= render(DiscountComponent.new(item: @item)) %>

결과는 다음과 같습니다.

ViewComponent Gem 소개

멋지지 않나요?

도우미

전통적인 Rails 보기에서는 보기에서 메서드 이름을 호출하여 도우미를 쉽게 연결할 수 있지만 보기 구성 요소에서는 다르게 작동합니다. 뷰 구성 요소에서 도우미 메서드는 뷰에서 직접 호출할 수 없지만 구성 요소에 포함될 수 있습니다. 이미 courses_helper.rb가 있습니다. CoursesController가 생성될 때 자동으로 생성된 파일이니 잘 활용해보자. 먼저 지금까지 과정에 등록한 사람의 수를 알려주는 도우미 메서드를 만들어 보겠습니다. 값을 가격의 4분의 1로 합시다:).

module CoursesHelper
  def count_enrollees(course)
    count = (course.price / 4).round()
    tag.p "#{count} enrollees so far"
  end
end

다음으로 도우미를 호출할 구성 요소를 만듭니다. 이것은 우리 보기에서 렌더링될 구성 요소입니다. 여기에 include 도우미를 포함한 문을 포함하고 이 구성 요소 내에서 도우미의 모든 메서드를 호출할 수 있습니다.

# app/components/enrollee_component.rb
class EnrolleeComponent < ViewComponent::Base
include CoursesHelper

  def total_enrollees(course)
    count_enrollees(course)
  end
end

마지막 단계는 과정을 표시하는 보기에 EnrolleeComponent를 추가하는 것입니다.

# app/components/course_component.html.erb
<%= EnrolleeComponent.new.total_enrollees(@item) %>

EnrolleeComponent에는 뷰가 없고 출력은 호출된 도우미 메서드의 출력이므로 EnrolleeComponent에 대해 렌더링 단어를 사용하지 않습니다. 결과는 다음과 같습니다.

ViewComponent Gem 소개

도우미는 아이콘, 중력자 또는 원하는 무엇이든 사용할 수 있습니다. ViewComponent는 도우미 사용을 변경하지 않습니다. 구성 요소에서 호출하는 방법만 변경됩니다.

before_render 메소드

ViewComponent는 before_render를 제공합니다. 구성 요소가 렌더링되기 전에 호출할 수 있는 메서드입니다. 할인 안내 옆에 별표를 추가해 보겠습니다. 별을 가져오는 도우미 메서드를 추가하는 것으로 시작합니다. star.png 이미지도 다운로드되어 app/assets/images에 배치되었습니다. 폴더.

#app/helpers/courses_helper.rb
def star_icon
  image_tag("/assets/star.png", width: "1%")
end

before_render를 추가해 보겠습니다. 이 도우미 메서드를 호출하는 할인 구성 요소에 메서드를 추가합니다.

# app/components/discount_component.rb
def before_render
  @star_icon = helpers.star_icon
end

위에서 볼 수 있듯이 도우미를 호출하는 또 다른 방식이 도입되었습니다. helpers.method를 사용하여 도우미를 호출할 수도 있습니다. component.rb 파일에서 그런 다음, DiscountComponent에 대한 렌더링 메서드에 별표 아이콘을 입력합니다. 이제 @star_icon을 통해 사용할 수 있습니다. 변수.

# app/components/discount_component.html.erb
<p class="green"> <%= @star_icon %> A 10% discount is available on this course </p>

결과는 다음과 같습니다.

ViewComponent Gem 소개

before_render에 반드시 도우미를 사용할 필요는 없습니다. 일하는 방법. 도우미 메서드를 호출하는 또 다른 접근 방식을 소개하기 위해 도우미를 사용했습니다.

미리보기

Action Mailer와 마찬가지로 ViewComponent를 사용하면 구성 요소를 미리 볼 수 있습니다. 이것은 먼저 config/application.rb에서 활성화해야 합니다. 파일.

config.view_component.preview_paths << "#{Rails.root}/lib/component_previews"

미리보기 구성요소는 test/components/previews에 있습니다. 여러 다른 입력이 전달된 구성 요소를 미리 보는 데 사용할 수 있습니다. DiscountComponent를 미리 볼 것입니다.

# test/components/previews/discount_component_preview.rb
class DiscountComponentPreview < ViewComponent::Preview
  def with_first_course
    render(DiscountComponent.new(item: Course.find(1)))
  end

  def with_second_course
    render(DiscountComponent.new(item: Course.find(2)))
  end
end

다른 시나리오에서 DiscountComponent를 미리 보기 위해 두 가지 방법이 추가되었습니다. 이를 보려면 https://localhost:3000/rails/view_components를 방문하십시오. , 생성된 모든 미리 보기 구성 요소와 해당 메서드를 찾을 수 있습니다. 아래에 표시된 것처럼 그것들 중 하나를 클릭하여 어떻게 생겼는지 볼 수 있습니다.

ViewComponent Gem 소개

위의 비디오에서 볼 수 있듯이 첫 번째 과정은 할인 구성 요소를 렌더링하지만 두 번째 과정에서는 아무 것도 렌더링되지 않습니다. 왜 이런 일이 일어났는지 아십니까? render? 메서드 확인이 발생했습니다. 첫 번째 시나리오는 비용 가격이 100유로 이상(1차 코스)이지만 비용이 2차 코스에 100유로 미만인 경우입니다. 메서드 이름은 여기에 강조 표시되기 전에 원인을 파악할 수 있도록 더 설명적이지 않았습니다 :).

show_previews를 사용하여 모든 환경에서 미리보기를 활성화하거나 비활성화할 수 있습니다. 옵션이지만 개발 및 테스트 환경에서는 기본적으로 활성화되어 있습니다.

# config/environments/test.rb
config.view_component.show_previews = false

JS 및 CSS 포함

"사이드카" 자산 또는 파일이라고도 하는 구성 요소와 함께 JavaScript 및 CSS를 포함할 수 있습니다. 이것은 아직 실험적인 기능입니다. 따라서 이 기사에서는 내부 작동에 대해 자세히 다루지 않겠지만 여기에서 이 ViewComponent 기능에 대해 자세히 알아볼 수 있습니다.

템플릿

뷰 구성요소의 템플릿은 여러 가지 방법으로 정의할 수 있습니다. 더 간단한 옵션은 아래와 같이 뷰와 컴포넌트를 동일한 폴더에 삽입하는 것입니다.

ViewComponent Gem 소개

여기에서 볼 수 있듯이 app/components에 모든 구성 요소와 보기가 있습니다. 폴더.

또 다른 옵션은 구성요소와 이름이 같은 하위 디렉토리에 보기 및 기타 자산을 배치하는 것입니다. 따라서 app/components에서 폴더에는 component.rb가 있습니다. 구성 요소가 들어 있는 파일과 별도의 course_component course_component.html.erb 보기가 있는 폴더 Course_component와 관련된 기타 모든 자산.

ViewComponent Gem 소개

명령줄에서 이러한 방식으로 구성 요소 파일을 생성하려면 --sidecar 플래그가 필요합니다:

rails g component Example name  --sidecar

이를 통해 css 및 js 파일을 구성 요소 폴더에 추가할 수 있습니다. ViewComponents는 call을 정의하여 템플릿 파일 없이도 렌더링할 수 있습니다. 방법. 이에 대한 예는 슬롯에 대해 논의하는 다음 섹션에서 제공됩니다. .

슬롯

슬롯을 사용하여 여러 콘텐츠 블록을 단일 ViewComponent에 전달할 수 있습니다. . has_one과 유사 및 has_many Rails 모델의 속성에서 슬롯은 renders_one으로 정의됩니다. 및 renders_many :

  • renders_one은 구성요소당 최대 한 번 렌더링되는 슬롯을 정의합니다:renders_one :header.
  • renders_many는 구성요소별로 여러 번 렌더링할 수 있는 슬롯(renders_many :titles)을 정의합니다.

사용 가능한 모든 코스의 제목과 헤더를 렌더링하는 페이지를 갖고 싶다고 상상해 보십시오. 이것은 슬롯을 사용하여 달성할 수 있습니다. . ListComponent를 만들어 봅시다. , 한 번만 렌더링되는 헤더와 TitleComponent , 많은 제목을 렌더링합니다.

#app/components/list_component.rb
class ListComponent < ViewComponent::Base
  renders_one :header, "HeaderComponent"
  # `HeaderComponent` is defined within this component, so we refer to it using a string.
  renders_many :titles, TitleComponent
  # `titleComponent` will be defined in another file, so we can refer to it by class name.
  class HeaderComponent < ViewComponent::Base
    def call
      content_tag :h1, content
    end
  end
end

위의 구성 요소에서 헤더는 한 번 렌더링되지만 이 페이지에는 많은 제목이 포함되므로 제목은 여러 번 렌더링된다고 명시했습니다. ListComponent 내에 HeaderComponent도 정의했습니다. 예, 이것은 ViewComponent에서 가능합니다. 클래스는 다른 클래스 내에서 정의될 수 있습니다. 또한 앞서 템플릿 섹션에서 설명한 호출 방법과 HeaderComponent에서 h1 태그를 렌더링하는 데 사용되어 해당 보기(html.erb 파일)가 필요하지 않은 방법도 살펴보겠습니다. ListComponent에 대한 해당 HTML 파일에는 다음이 포함됩니다.

#app/components/list_component.html.erb
<div>
  <%= header %> <!-- renders the header component -->
  <% titles.each do |title| %>
    <div>
      <%= title %> <!-- renders an individual course title -->
    </div>
  <% end %>
</div>

html 파일에 헤더를 포함하고 구성 요소에 전달된 모든 제목을 반복하고 렌더링했습니다. 보시다시피 목록 보기 파일에서 렌더링할 구성 요소의 이름을 지정할 필요가 없습니다. 우리 슬롯이 그것을 처리했습니다. 따라서 header로 식별합니다. 및 title .

다음 단계는 전달된 모든 제목에 대해 렌더링될 것이므로 TitleComponent 및 해당 HTML 파일을 만드는 것입니다.

# app/components/title_component.rb
class TitleComponent < ViewComponent::Base
  def initialize(title:)
    @title = title
  end
end
# app/components/title_component.html.erb
<div>
  <h3> <%= @title %> </h3>
</div>

마지막으로 index.html에서 파일을 임시로 지우고 ListComponent 렌더로 교체해 보겠습니다.

#app/views/courses/index.html.erb
<%= render ListComponent.new do |c| %>
  <% c.header do %>
  <%= link_to "List of Available Courses", root_path %>
  <% end %>
  <%= c.title(title: "First title") %>
  <%= c.title(title: "Second title!") %>
<% end %>

ViewComponent Gem 소개

이제 코스를 컬렉션으로 이 뷰에 전달해 보겠습니다. 컬렉션을 슬롯에 전달하려면 초기화에 필요한 변수를 포함하는 객체의 배열로 컬렉션을 전달해야 합니다. 보시다시피 전달된 모든 과정은 제목 인수로 초기화되어야 합니다. db에 있는 모든 과정의 제목을 해시 배열로 추출하여 렌더링할 수 있습니다.

ViewComponent Gem 소개

이제 여러 타이틀 목록을 단일 c.titles로 바꿀 수 있습니다. 컬렉션의 경우 course_titles 변수를 사용하여 정의한 제목 해시에 전달합니다. .

# app/views/courses/index.html.erb
<% course_titles = Course.all.pluck(:title).map { |title| {title: title}} %>

<% c.titles(course_titles) %>

결과는 다음과 같습니다.

ViewComponent Gem 소개

이것이 바로 슬롯이 작동하는 방식입니다. 단일 ViewComponent 내에서 여러 구성 요소를 렌더링합니다. 슬롯은 다른 여러 방법으로 렌더링할 수 있으며 여기에서 자세한 정보를 찾을 수 있습니다.

테스트

보기 구성 요소 테스트는 테스트 파일에 "view_component/test_case"를 요구하고 render_inline을 사용하여 수행됩니다. 렌더링된 출력에 대해 어설션이 만들어지도록 도우미를 테스트합니다. 먼저 DiscountComponent를 테스트해 보겠습니다.

require "test_helper"
require "view_component/test_case"

class DiscountComponentTest < ViewComponent::TestCase
  def test_render_component
    render_inline(DiscountComponent.new(item: "my item"))
  end
end

rails test test/components/discount_component_test.rb 명령을 사용하여 이 테스트를 실행할 때 , 다음 오류가 발생합니다.

ViewComponent Gem 소개

이것은 우리가 통과한 것처럼 항목이 가격 속성이 아니라 가격 속성이 있는 코스여야 하기 때문에 테스트가 올바른 구성 요소에 도달하고 있지만 적절한 소품이 부족하다는 것을 증명합니다. 또한 render?가 있음을 알려줍니다. 이 구성 요소가 렌더링되기 전에 확인 중인 메서드입니다. 이제 올바른 변수를 전달해 보겠습니다.

def test_render_component
  course = Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')
  render_inline(DiscountComponent.new(item: course))
end

성공적으로 실행됩니다. 이 테스트에 어설션을 추가해 보겠습니다.

def test_render_component
  course = Course.create(title: 'Organizing your Time', price: 155.00, location: 'London')
  render_inline(DiscountComponent.new(item: course))
  assert_selector 'p[class="green"]'
  assert_text "10% discount"
end

이 테스트도 통과했습니다. 이 구성 요소에 대한 렌더링 조건이 있음을 기억하십시오. ViewComponent는 refute_component_rendered를 사용하여 구성 요소가 렌더링되지 않았는지 테스트하는 방법도 제공하므로 걱정하지 마십시오. . 가격이 100유로 미만인 코스를 사용하여 이를 테스트할 수 있습니다.

def test_component_not_rendered
  course = Course.create(title: 'Organizing your Time', price: 55.00, location: 'London')
  render_inline(DiscountComponent.new(item: course))
  refute_component_rendered
end

이 테스트도 통과했습니다.

CourseComponent가 그 안에 중첩된 모든 구성 요소를 렌더링하는지 테스트하기 위해 또 다른 테스트를 작성해 보겠습니다.

require "test_helper"
require "view_component/test_case"

class CourseComponentTest < ViewComponent::TestCase
  def test_component_renders_all_children
    course = Course.create(title: 'Organizing your Time', price: 155.00, location: 'London')
    render_inline(CourseComponent.new(item: course, notice: 'A new test', item_counter: 1))
    assert_selector("h2", text: "Organizing your Time")
    assert_selector("h4", text: "€155.00")
    assert_selector("h4", text: "London")
    assert_text("enrollees")
    assert_text("discount")
  end
end

이 테스트도 통과합니다. Enrollee 및 Discount 구성 요소도 제대로 렌더링되는지 테스트합니다.

슬롯 구성 요소가 있고 아래 이미지와 같이 하나의 헤더와 많은 제목을 렌더링한다는 것을 기억하십시오.

ViewComponent Gem 소개

이를 테스트하기 위해 헤더와 렌더링해야 하는 제목이 포함된 코드 블록을 구성 요소에 전달한 다음 렌더링된 구성 요소에 대해 주장할 수 있습니다.

require "test_helper"
require "view_component/test_case"

class ListComponentTest < ViewComponent::TestCase
  def test_renders_slots_with_content
  render_inline(ListComponent.new) do |component|
  component.header { "A Test List" }
  component.titles [{title: 'Test title 1'}, {title: 'Test title 2'}]
  end

  assert_selector("h1", text: "A Test List")

  assert_text("Test title 1")
  assert_text("Test title 2")
  end
end

이 테스트도 통과했습니다 :).

Rspec 테스팅

테스트에 대해 위에서 말한 모든 것 외에도 선호하는 테스트 프레임워크가 RSpec인 경우 ViewComponents에 대해 RSpec을 활성화하려면 몇 가지 추가 구성을 수행해야 합니다.

# spec/rails_helper.rb
require "view_component/test_helpers"
require "capybara/rspec"

RSpec.configure do |config|
  config.include ViewComponent::TestHelpers, type: :component
  config.include Capybara::RSpecMatchers, type: :component
end

우리의 DiscountComponent 테스트는 아래와 같이 Rspec을 사용하여 다시 작성하고 다시 테스트할 수 있습니다.

require "rails_helper"

RSpec.describe DiscountComponent, type: :component do

  it "renders the component correctly" do
    course = Course.create(title: 'Organizing your Time', price: 155.00, location: 'London')
    render_inline(DiscountComponent.new(item: course))
    expect(rendered_component).to have_css "p[class='green']", text: "10% discount"
    expect(rendered_component).to have_css "img[src*='/assets/star.png']"
  end
end

이 테스트는 우아하게 통과합니다. 네, 별 아이콘이 보입니다.

결론

Rails 앱을 위한 여러 뷰 구성 요소를 작성하면 코드를 더 읽기 쉽게 만들고 원치 않는 합병증으로 인한 오류가 발생하지 않을 뿐만 아니라 HTTP 요청 중에뿐만 아니라 격리된 상태에서 뷰를 테스트할 수 있습니다. 보기 구성 요소는 기존 Rails 앱에 쉽게 주입할 수 있으며 대부분 재사용되는 보기부터 시작하는 것이 가장 좋습니다. 지금까지 배운 모든 내용을 바탕으로 이것은 쉬운 작업이어야 합니다. 그럼에도 불구하고 ViewComponent에 대한 더 많은 정보를 원하시면 주저하지 말고 해당 문서나 RubyDoc 정보를 살펴보십시오.