Как проверить Концерн в Rails

Учитывая, что у меня естьPersonable беспокойство в моем приложении Rails 4, которое имеетfull_name метод, как бы я пошел о тестировании этого с помощью RSpec?

относится к / personable.rb

module Personable
  extend ActiveSupport::Concern

  def full_name
    "#{first_name} #{last_name}"
  end
end
 Kyle Decot13 мая 2013 г., 17:25
Не проблема. Всегда приятно узнать мнение других разработчиков на эту тему.м в настоящее время имеет дело с
 Lee Jarvis13 мая 2013 г., 17:05
Какие рамки тестирования вы используете? Также помните, что Personable - это обычный модуль Ruby. Протестируйте это так же, как и любой другой миксин.
 Russell13 мая 2013 г., 17:18
:-) Согласен. Прости, Кайл!
 Lee Jarvis13 мая 2013 г., 17:16
@ Рассел Я согласен. Тем не менее, я бы нене помогать кому-то с его вопросами только потому, что он следовал Rails-у, делая то, что я не делалне согласен с этим Во всяком случае, это своего рода уход от предмета этого вопроса :-)
 Russell13 мая 2013 г., 17:06
Имеет неActiveSupport::Concern были вывезены из рельсов? Я думал, что это прошло некоторое время назад.
 Lee Jarvis13 мая 2013 г., 17:09
 Russell13 мая 2013 г., 17:14
@LeeJarvis By "Rails core " Я полагаю, вы имеете в видуDHH», Это'определенно не очень хорошая идея делать что-то только потому, чтоRails core " говорит сделать это так.
 Russell13 мая 2013 г., 17:09
Ах, Google сообщает мне, что это был толькоInstanceMethods модуль внутриConcern это было удалено. Я все еще думаю, что проблемы плохой дизайн, хотя. Какие'не так с объектами обслуживания?
 Lee Jarvis13 мая 2013 г., 17:10
@Russell Rails 4 активно продвигает проблемы (я также согласен, что сервисные объекты - лучшая идея), но, к сожалению, это 'Это не так, как видит ядро Rails. Люди просто должны помнить, что ониэто просто нормальные модули Ruby и должны использоваться соответствующим образом.
 Kyle Decot13 мая 2013 г., 17:08
@ LeeJarvis I 'используя Rspec вместе с FactoryGirl

Ответы на вопрос(3)

Решение Вопроса

Метод, который вы нашли, безусловно, будет работать, чтобы протестировать немного функциональности, но кажется довольно хрупким -ваш фиктивный класс (на самом деле простоStruct в вашем решении) может или не может вести себя как реальный класс, которыйincludeтвоя забота Кроме того, если выВы пытаетесь проверить модельные проблемы, вы выигралине может выполнять такие вещи, как проверка достоверности объектов или вызывать обратные вызовы ActiveRecord, если вы не настроите базу данных соответствующим образом (поскольку ваш фиктивный класс выигралэто не база данных базы данных). Кроме того, выЯ хочу не только проверить беспокойство, но и проверить беспокойствоповедение внутри вашей модели спецификации.

Так почему бы не убить двух зайцев одним выстрелом? Используя RSpec'sобщие примеры группвы можете проверить свои опасения по отношению к реальным классам, которые их используют (например, модели)а также вы'Я смогу проверить их везде, где ониповторно используется. И вам нужно только написать тесты один раз, а затем просто включить их в любую спецификацию модели, которая использует вашу заботу. В вашем случае это может выглядеть примерно так:

# app/models/concerns/personable.rb

module Personable
  extend ActiveSupport::Concern

  def full_name
    "#{first_name} #{last_name}"
  end
end

# spec/concerns/personable_spec.rb

require 'spec_helper'

shared_examples_for "personable" do
  let(:model) { described_class } # the class that includes the concern

  it "has a full name" do
    person = FactoryBot.build(model.to_s.underscore.to_sym, first_name: "Stewart", last_name: "Home")
    expect(person.full_name).to eq("Stewart Home")
  end
end

# spec/models/master_spec.rb

require 'spec_helper'
require Rails.root.join "spec/concerns/personable_spec.rb"

describe Master do
  it_behaves_like "personable"
end

# spec/models/apprentice_spec.rb

require 'spec_helper'

describe Apprentice do
  it_behaves_like "personable"
end

Преимущества этого подхода становятся еще более очевидными, когда вы начинаете делать вещи, которые вас интересуют, например, вызывать обратные вызовы AR, когда что-то меньшее, чем объект AR только что выиграл »т делать

 Sergio Belevskij24 мар. 2017 г., 17:48
Это'Это очень, очень полезно для меня!
 Pak13 янв. 2015 г., 17:07
 Jake Smith28 дек. 2014 г., 03:08
Я не могне найти что-либо о включении каталога проблем в этой ссылке. Не могли бы вы уточнить, как это делается? Я могу'Мой тест RSpec не может распознать модуль в одной из моих проблем.
 Steve Hill02 июл. 2015 г., 17:23
Единственное, что меня здесь привлекло, это то, что мне нужно было создать экземпляр моей модели, а не просто использовать класс.let(:model) { described_class } нужно бытьlet(:model) { described_class.new } чтобы избежать неприятного.NoMethodError: undefined method `reflect_on_association' for Class:Class
 Aaron K10 апр. 2014 г., 00:16
@ArtemKalinchuk I 'я не уверен, чтоправда, согласноgithub.com/grosser/parallel_tests/issues/168 parallel_tests основаны на файл, поэтому общие примеры не должны замедлять его. Я бы также поспорил, что правильно сгруппированные общие поведенческие функции бьют по скорости тестирования.
 Lalu11 мар. 2016 г., 17:18
Не добавлять_spec к имени файла, который содержит shared_examples_for (personable_spec.rb в данном случае), в противном случае вы получите вводящее в заблуждение предупреждающее сообщение -github.com/rspec/rspec-core/issues/828.
 Artem Kalinchuk21 янв. 2014 г., 13:23
Одним из недостатков этого является то, что он будет замедлятьсяparallel_tests, Я думаю, что будет лучше иметь отдельные тесты, а не использоватьshared_examples_for а также .it_behaves_like
 Ziggy06 июн. 2014 г., 02:20
Не забудьте включитьconcerns каталог в вашемspec_helper.rb github.com/rspec/rspec-core/issues/407#issuecomment-1409871
 David Hempy21 февр. 2019 г., 17:49
Вы могли бы, вероятно, создать свой экземпляр вместо .create и сделать турбонаддув своими тестами.

Другая мысль заключается в использованииwith_model gem чтобы проверить такие вещи. Я искал, чтобы проверить беспокойство сам и виделэто делает гем pg_search, Кажется, это намного лучше, чем тестирование на отдельных моделях, поскольку они могут измениться, и это 'приятно определять вещи, которые тыВы будете нуждаться в вашей спецификации.

В ответ на комментарии ямы получили здесьчто ямы закончили тем, что делали(если у кого-то есть улучшения, пожалуйста, не стесняйтесь их публиковать):

спецификации / проблемы / personable_spec.rb

require 'spec_helper'

describe Personable do
  let(:test_class) { Struct.new(:first_name, :last_name) { include Personable } }
  let(:personable) { test_class.new("Stewart", "Home") }

  it "has a full_name" do
    expect(personable.full_name).to eq("#{personable.first_name} #{personable.last_name}")
  end
end
 Edward04 авг. 2016 г., 19:36
Прекрасно работает и выглядит красиво
 Kyle Decot14 мая 2013 г., 15:14
Отлично работает сейчас. Спасибо, что указали мне правильное направление и помогли мне провести рефакторинг @Russell
 Kyle Decot13 мая 2013 г., 20:29
Это нет работа. Это дает мне ошибку:undefined method 'full_name' for #
 Russell13 мая 2013 г., 17:25
Да, это сломает другие тесты, если они будут тестировать реальный класс с именемPerson, Я'Буду редактировать, чтобы исправить.
 Russell13 мая 2013 г., 23:45
Попробуйте включить Personable, а не расширять его. Я'уточню ответ.

Ваш ответ на вопрос