2011-02-03 3 views
6

Я новичок в Rspec и пытаюсь настроить тест для профиля пользователя. Профиль принадлежит_то пользователю.Rspec Mocking: ActiveRecord :: AssociationTypeMismatch

Теперь у меня есть интеграция API с сторонним сайтом, который работает через пользовательскую модель, но часть информации для этой ссылки API содержится в профиле, поэтому у меня есть фильтр «after_update» в профиле, который сообщает родительский пользователь для сохранения, который запускает обновление API.

Я пытаюсь написать тест для этого, и я получаю ActiveRecord :: AssociationTypeMismatch. Причина в том, что я использую макет пользователя, но я пытаюсь проверить, что когда профиль обновляется, он отправляет: save to User. Кроме того, у модели пользователя есть процесс подтверждения электронной почты, а входящие API-вызовы в процессе создания, поэтому на самом деле не идеально, чтобы фактически создать пользователя, чтобы проверить это.

Вот мой тест:

it "should save the parent user object after it is saved" do 
    user = double('user', :save => true) 
    profile = Profile.create(:first_name => 'John', :last_name => 'Doe') 
    profile.user = user 

    user.should_receive(:save) 
end 

Таким образом, очевидно, ошибка ActiveRecord, вызвана пытается связать макет пользователя с профилем, который ожидает реальный пользователь ассоциироваться.

Вопрос в том, как избежать такой проблемы при написании тестов на рельсы? Все, что я хочу, чтобы этот тест выполнял, - это удостовериться, что запрос профиля: сохранить его родительский пользователь. Есть ли более разумный способ сделать это или обходной путь для ошибки ActiveRecord?

Спасибо!

+0

Лично я хотел бы использовать что-то наподобие factory_girl для создания уже подтвержденного объекта User, а затем установить для него «save». Вы не можете подделать подтвержденного пользователя, не пройдя процесс электронной почты? Это вызывает некоторые тревоги в отношении дизайна кода. –

+0

Ну, ваше предложение закончилось тем, что мне нужно было идти. Я смог изолировать API, который я не хотел вызывать, сообщая контроллеру, чтобы он не вызывал этот вызов в тестовой среде, так что позвольте мне работать с объектами Factory, как ожидалось. Тем не менее, мне пришлось снова включить действия API для тестирования интеграции, поэтому в конце концов я просто отказался от этого подхода и позволил среде песочницы API получить полные мусорные данные, которые я должен периодически очищать. Не то, что я бы предпочел, но это позволяет мне проверить. – Andrew

ответ

3

Я нашел единственный способ, которым я был в состоянии обойти эту проблему, чтобы использовать пользователь Factory вместо издеваться. Это разочаровывает, но при тестировании обратных вызовов между двумя моделями ActiveRecord вам нужно использовать реальные модели, иначе сбой вызовов не удастся, жизненный цикл не произойдет, и обратные вызовы не могут быть протестированы.

+0

Не следует ли проверять обратные вызовы в соответствующей спецификации модели? – Starkers

11

Вы должны быть в состоянии использовать mock_model для этого:

it "should save the parent user object after it is saved" do 
    user = mock_model(User) 
    user.should_receive(:save).and_return(true) 
    profile = Profile.create(:first_name => 'John', :last_name => 'Doe') 
    profile.user = user 
end 
+0

Я пробовал это, и это не сработало. – Andrew

+2

Что конкретно? – zetetic

+0

Работает. Благодаря! –

Смежные вопросы