Factory bot Flashcards

You may prefer our related Brainscape-certified flashcards:
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() ?

A

Нет

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
Q

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

A

Использовать метод association ()
factory :post do
# …
# сразу создается и связанный объект author
association :author, factory: :user, last_name: “Writely”
end
Первый параметр - это имя связи,
второй параметр - это имя фабрики для связанной модели
третьим параметром можно переопределить атрибуты связанной фабрики

26
Q

Нужно ли использовать метод association(), если имя связанной модели совпадает с именем связи ?

A
нет, не нужно
factory :post do
  # ...
  author # имя фабрики совпадает с именем ассоциации для post
end
27
Q

Поведение метода association() меняется в зависимости от стратегии создания объекта.
Как явно передать стратегию создания связанного объекта?

A

Использовать параметр 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
Q

Можно ли использовать параметр strategy: :build в описании неявных ассоциациях?

A

Нет, это приведет к ошибке.
factory :post do
# …
author strategy: :build # «< это не сработает, потому что author_id будет nil

29
Q

Для чего нужны последовательности sequence ?

A

Для генерации однотипных уникальных значений (атрибутов)

# Определяет новую последовательность
FactoryBot.define do
  sequence :email do |n|
    "person#{n}@example.com"
  end
end
generate :email
# => "person1@example.com"
generate :email
# => "person2@example.com"
30
Q

Последовательности также могут иметь псевдонимы (alias).
factory :user do
sequence(:email, 1000, aliases: [:sender, :receiver]) { |n| “person#{n}@example.com” }
end
Как это влияет на счетчик последовательности?

A

Счетчик общий для всех псевдонимов

# увеличит значение счетчика для :email, также и для :sender и для :receiver
generate(:sender)
31
Q

Должен ли счетчик последовательности всегда быть числом ?

A

Счетчиком может быть и строка. Главное, чтобы тип данных поддерживал метод #next

factory :user do
sequence(:email, ‘a’, aliases: [:sender, :receiver]) { |n| “person#{n}@example.com” }
end

32
Q

Можно ли сбросить счетчик последовательности?

A

Да, с помощью метода 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
Q

Для чего используются traits в factoru\y bot?

A

Для создания групп атрибутов, чтобы использовать их в любой фабрике.

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