Проверка ассоциаций ActiveRecord в RSpec

17

Я изучаю, как писать тестовые примеры с помощью Rspec. У меня есть простая публикация комментариев, которые могут содержать много комментариев. Я тестирую это с помощью Rspec. Как я должен проверять Post :has_many :comments . Должен ли я заглушить метод Post.comments , а затем проверить это, возвращая макет объекта массива объектов комментариев? Действительно ли требуется тестирование для ассоциаций AR?

    
задан Alok Swain 20.04.2010 в 08:30
источник

4 ответа

28

Так как ассоциации ActiveRecord должны быть хорошо протестированы набором тестов Rails (и они есть), большинство людей не чувствует необходимости убедиться, что они работают - предполагается, что они будут.

Если вы хотите убедиться, что ваша модель использует эти ассоциации, это что-то другое, и вы не ошибаетесь, если хотите проверить это. Мне нравится делать это с помощью shoulda gem. Он позволяет вам делать такие простые вещи:

describe Post do
  it { should have_many(:comments).dependent(:destroy) }
end
    
ответ дан Robert Speicher 20.04.2010 в 09:05
источник
  • Спасибо! теперь получил довольно четкое представление. –  Alok Swain 20.04.2010 в 09:34
  • Пункты, дважды проверьте это. Я имел в виду Драгоценный камень Вста, а не заводскую. –  Robert Speicher 20.04.2010 в 09:40
12

Тестирование ассоциаций - хорошая практика, особенно в среде, где TDD очень ценится. Другие разработчики часто будут смотреть на ваши спецификации, прежде чем смотреть на соответствующий код. Тестирование ассоциаций гарантирует, что ваш файл спецификации наиболее точно отражает ваш код.

Два способа тестирования ассоциаций:

  1. С FactoryGirl:

    expect { FactoryGirl.create(:post).comments }.to_not raise_error
    

    Это относительно поверхностный тест, который будет с фабрикой, например:

    factory :post do
      title { "Top 10 Reasons why Antelope are Nosy Creatures" }
    end
    

    возвращает вам NoMethodError, если в вашей модели отсутствует ассоциация has_many с комментариями.

  2. Вы можете использовать метод ActiveRecord #reflect_on_association , чтобы принять более подробно посмотрите на свою ассоциацию. Например, с более сложной ассоциацией:

    class Post
      has_many :comments, through: :user_comments, source: :commentary
    end
    

    Вы можете более глубоко изучить вашу ассоциацию:

    reflection = Post.reflect_on_association(:comment)
    reflection.macro.should eq :has_many
    reflection.options[:through].should eq :user_comments
    reflection.options[:source].should eq :commentary
    

    и проверить, какие параметры или условия релевантны.

ответ дан mhriess 09.02.2013 в 00:04
источник
1

Если вы не хотите использовать внешний камень, например shoulda , чтобы проверить свои ассоциации (см. Robert Speicher Ответ для получения более подробной информации на этом), другой вариант - использовать reflect_on_association , чтобы получить AssociationReflection объекта для соответствующей ассоциации, а затем утверждать, что:

describe Post do
  it "should destroy its comments when it is destroyed" do
    association = Post.reflect_on_association(:comments)

    expect(association).to_not be_nil
    expect(association.options[:dependent]).to eq :destroy
  end
end
    
ответ дан Ajedi32 18.09.2014 в 17:44
источник
0

Большинство людей не тестируют ассоциации, так как Rails уже имеет модульные тесты, чтобы убедиться, что эти методы работают правильно. Если вы делаете что-то сложное, например, вовлечение в процесс или что-то еще, вы можете явно протестировать его. Обычно вы можете сделать это, просто сделав

a = Post.new
a.comments << Comment.new
assert a.save
assert a.comments.size == 1

или что-то похожее на это.

    
ответ дан Preston Marshall 20.04.2010 в 08:37
источник
  • Я получил тебя частично. Я новичок в тестировании. Скажем, я пишу модульный тест, чтобы убедиться, что все комментарии удалены, когда связанная почта удалена. Так что этого достаточно? Кроме того, мне даже требуется написать единичный тест, чтобы проверить метод уничтожения, созданный строительными лесами. –  Alok Swain 20.04.2010 в 08:48