Factory bot Flashcards

(33 cards)

1
Q

Как включить Factory bot в свой Rails проект ?

A

в Gemfile написать:

group :development, :test do
gem ‘factory_bot_rails’
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Как отключить использование factory bot для замены fixtures в моем Rails приложении

A

в application.rb :

config.generators do |g|
g.factory_bot false
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Для чего нужен Factory bot ?

A

Для автоматической замены fixtures

  • при создании шаблонов тестов генераторами,
  • при использовании в тестовых случаях
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Какой каталог фабрик по умолчанию ?

A

test/factories
или
spec/factories

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Как изменить каталог фабрик по умолчанию ?

A

в файле application.rb:

config.generators do |g|
g.factory_bot dir: ‘custom/dir/for/factories’
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Что будет, если гем factory_bot_rails не включен в группу development ?

A

Генераторы Rails будут генерировать стандартные файла фикстур .yml

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

В каком файле описаны определения всех фабрик?

A

factories.rb в каталоге с тестами по умолчанию.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Какие настройки и куда нужно внести, чтобы использовать factory bot с гемом Rspec?

A

файл spec/support/factory_bot.rb

RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end

Затем в rails_helper.rb загрузить этот файл
require ‘support/factory_bot’

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Какие настройки и куда нужно внести, чтобы использовать factory bot с Test::Unit ?

A

Просто включить модуль в класс теста

class Test::Unit::TestCase
include FactoryBot::Syntax::Methods
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Какие настройки и куда нужно внести, чтобы использовать factory bot с Minitest ?

A

Просто включить модуль в класс теста

class Minitest::Unit::TestCase
include FactoryBot::Syntax::Methods
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Каким образом описывается формирование одной фабрики?

A
# Тут будет угадана модель User
FactoryBot.define do
  factory :user do
    first_name "John"
    last_name  "Doe"
    admin false
  end
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Как для одного класса модели задать более одной фабрики?

A
FactoryBot.define do
  # Тут будет использован явно указанный класс модели User (модель Admin не будет угадываться)
  factory :admin, class: User do
    first_name "Admin"
    last_name  "User"
    admin      true
  end
end
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Из каких мест приложения будут загружаться фабрики при выполнении метода
FactoryBot.find_definitions ?

A

test/factories.rb
spec/factories.rb
test/factories/.rb
spec/factories/
.rb

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

Какие стратегии создания объектов из фабрик поддерживает factory bot?

A
# Возвращает не сохраненный экземпляр User
user = build(:user)
# Возвращает сохраненный экземпляр User
user = create(:user)
# Возвращает hash аттрибутов который может быть использован для создания экземпляра класса User
attrs = attributes_for(:user)
# Возвращает объект со всеми выделенными (stubbed out) аттрибутами
stub = build_stubbed(:user)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Можно ли передавать блоки методам создания объектов ?

A

При передаче блока любому из этих методов экземпляр, созданный фабрикой, прокидывается внутрь блока
create(:user) do |user|
user.posts.create(attributes_for(:post))
end

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Можно ли переопределить значения атрибутов фабрики при создании объектов ?

A

Да, независимо от стратегии стратегии создания

# Создаем экземпляр User и переопределяем свойство first_name
user = build(:user, first_name: "Joe")
user.first_name
# => "Joe"
17
Q

Как в factory bot описать динамические атрибуты?

A
factory :user do
  # ...
  activation_code { User.generate_activation_code }
  date_of_birth   { 21.years.ago }
end
18
Q

Для чего в описании фабрик используются псевдонимы Alisces ?
factory :user, aliases: [:author, :commenter] do
first_name “John”
last_name “Doe”
date_of_birth { 18.years.ago }
end

A

Чтобы упростить их повторное использовние в фабриках связанных моделей

factory :post do
  author
  # вместо
  # ассоциации :author, factory: :user
  title "How to read a book effectively"
  body  "There are five steps involved."
end
factory :comment do
  commenter
  # вместо
  # ассоциации :commenter, factory: :user
  body "Great article!"
end
19
Q

можно ли в фабриках задавать атрибуты зависящие от значений других атрибутов этой же фабрики?

A

Да, можно

factory :user do
  first_name "Joe"
  last_name  "Blow"
  email { "#{first_name}.#{last_name}@example.com".downcase }
end
create(:user, last_name: "Doe").email
# => "joe.doe@example.com"
20
Q

Что такое transient атрибуты и для чего они используются ?

A

Это способ объявления атрибутов в фабрике для выполнения принципа DRY. Используются для задания статических и динамических атрибутов фабрики

factory :user do
  transient do
    rockstar true
    upcased  false
  end

name { “John Doe#{“ - Rockstar” if rockstar}” }
email { “#{name.downcase}@example.com” }
….

21
Q

Доступны ли transient атрибуты в методе attributes_for() ?

22
Q

Можно ли использовать transient атрибуты в обратных вызовах?

A

Да, можно.
Для доступа к ним в блок обратного вызова нужно передать второй параметр evaluator

factory :user do
  transient do
    rockstar true
    upcased  false
  end

name { “John Doe#{“ - Rockstar” if rockstar}” }
email { “#{name.downcase}@example.com” }

# Это объявление обратного вызова
  after(:create) do |user, evaluator|
    user.name.upcase! if evaluator.upcased
  end
end
create(:user, upcased: true).name
#=> "JOHN DOE - ROCKSTAR"
23
Q

Как объявить атрибут фабрики, если его имя конфликтует с зарезервированными в factory_bot словами ?

A

Использовать метод add_attribute()
factory :dna do
add_attribute(:sequence) { ‘GATTACA’ }
end

factory :payment do
add_attribute(:method) { ‘paypal’ }
end

24
Q

Как работает наследование в определении фабрик?

A

Так
factory :post do
title “A title”

factory :approved_post do
approved true
end
end

approved_post = create(:approved_post)
approved_post.title # => “A title”
approved_post.approved # => true

или указать родителя явно

factory :post do
title “A title”
end

factory :approved_post, parent: :post do
approved true
end

25
Как использовать связи между моделями при описании фабрик?
Использовать метод association () factory :post do # ... # сразу создается и связанный объект author association :author, factory: :user, last_name: "Writely" end Первый параметр - это имя связи, второй параметр - это имя фабрики для связанной модели третьим параметром можно переопределить атрибуты связанной фабрики
26
Нужно ли использовать метод association(), если имя связанной модели совпадает с именем связи ?
``` нет, не нужно factory :post do # ... author # имя фабрики совпадает с именем ассоциации для post end ```
27
Поведение метода association() меняется в зависимости от стратегии создания объекта. Как явно передать стратегию создания связанного объекта?
Использовать параметр strategy: :build factory :post do # ... # сразу создается и связанный объект author association :author, factory: :user, strategy: :build end ``` # Создает User, а затем создает Post, но ничего не сохраняет post = build(:post) post.new_record? # => true post.author.new_record? # => true ```
28
Можно ли использовать параметр strategy: :build в описании неявных ассоциациях?
Нет, это приведет к ошибке. factory :post do # ... author strategy: :build # <<< это не сработает, потому что author_id будет nil
29
Для чего нужны последовательности sequence ?
Для генерации однотипных уникальных значений (атрибутов) ``` # Определяет новую последовательность FactoryBot.define do sequence :email do |n| "person#{n}@example.com" end end ``` ``` generate :email # => "person1@example.com" ``` ``` generate :email # => "person2@example.com" ```
30
Последовательности также могут иметь псевдонимы (alias). factory :user do sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" } end Как это влияет на счетчик последовательности?
Счетчик общий для всех псевдонимов ``` # увеличит значение счетчика для :email, также и для :sender и для :receiver generate(:sender) ```
31
Должен ли счетчик последовательности всегда быть числом ?
Счетчиком может быть и строка. Главное, чтобы тип данных поддерживал метод #next factory :user do sequence(:email, 'a', aliases: [:sender, :receiver]) { |n| "person#{n}@example.com" } end
32
Можно ли сбросить счетчик последовательности?
Да, с помощью метода FactoryBot.rewind_sequences sequence(:email) {|n| "person#{n}@example.com" } generate(:email) # "person1@example.com" generate(:email) # "person2@example.com" generate(:email) # "person3@example.com" FactoryBot.rewind_sequences generate(:email) # "person1@example.com"
33
Для чего используются traits в factoru\y bot?
Для создания групп атрибутов, чтобы использовать их в любой фабрике. factory :user, aliases: [:author] factory :story do title "My awesome story" author trait :published do published true end trait :unpublished do published false end trait :week_long_publishing do start_at { 1.week.ago } end_at { Time.now } end trait :month_long_publishing do start_at { 1.month.ago } end_at { Time.now } end factory :week_long_published_story, traits: [:published, :week_long_publishing] factory :month_long_published_story, traits: [:published, :month_long_publishing] factory :week_long_unpublished_story, traits: [:unpublished, :week_long_publishing] factory :month_long_unpublished_story, traits: [:unpublished, :month_long_publishing] end