Я столкнулся с этой проблемой с тестированием. Давайте предположим, что у меня есть две модели, Пользователь и Сообщение, где пользователь has_many: сообщения.
Я пробую к спецификации блок кода, который включает что-то вроде этого:
user = User.find(123)
post = user.posts.find(456)
Я знаю, как дразнить User.find
и user.posts
части. user.posts
дразните возвращает массив объектов Сообщения. И когда это get's к .find(456)
часть, все ломается с no block given
исключение.
Таким образом, мой вопрос здесь: что я возвращаю как результат user.posts
насмешка, так, чтобы .find(456)
метод работает над ним? User.first.posts.class
говорит, что это - Массив, но очевидно существует что-то больше, которое заставляет стиль AR найти вызовам работу. Я не вне себя от радости из-за перспективы насмешки, находят метод на возвращенном объекте.
PS перед предложением очевидного и хорошего ответа насмешки остановки об и использования приспособлений/отбора тестовая база данных с необходимыми данными вот является выгодой: схема прежней версии. И работа Пользователя и Сообщения сверху базы данных просматривает не таблицы и изменение его так, чтобы они были таблицами в тестовой базе данных, кажется неправильным мне.
Проблема в том, что user.posts
на самом деле не , а простой Array
; это объект прокси-сервера ассоциаций. Скорее всего, это нечто подобное (хотя точный синтаксис зависит от того, какой насмешливый фреймворк вы используете):
def setup
@user = mock(User)
User.stub(:find).with(123).return(@user)
user_posts = mock(Object)
@user.stub(:posts).return(user_posts)
@post = mock(Post)
user_posts.stub(:find).with(456).return(@post)
end
Затем в вашем тесте, User.find(123)
вернет @user
, а @user.post.find(456)
вернет @post
. Если вам нужно, чтобы @user.posts
в ваших тестах действовал как Array
, вы можете создать mock(Array)
и заглушить метод [](index)
.
Вы можете изучить метод stub_chain, предлагаемый RSpec.
Обновление: Per ryan2johnson9 обновленная документация это: https://relishapp.com/rspec/rspec-mocks/v/3-2/docs/working-with-legacy-code/message-chains