RSpec Mocks Вопрос для ActiveRecord Найти сначала с Где - PullRequest
0 голосов
/ 11 августа 2011

Я пытаюсь разобрать свои тесты RSpec для моего контроллера, но он не работает, и мне нужна помощь, чтобы выяснить это.

Мой Rspec:

  before(:each) do
    @topic = mock_model(Topic, :update_attributes => true)
    Topic.stub!(:where).with({:slug=>"some-slug"}).and_return(@topic)
    with_valid_user
  end

  it "should find topic and return object" do
    Topic.should_receive(:where).with("some-slug").and_return(@topic)
    put :update, :topic_slug => "some-slug", :topic => {}
  end

Логика контроллера, которую я пытаюсь проверить:

  def get_topic
    @topic = Topic.where(:slug => params[:topic_slug]).first
    @topic
  end

Но вывод, который я получаю:

 Failure/Error: Topic.stub!(:where).with({:slug=>"some-slug"}).first.and_return(@topic)
 NoMethodError:
   undefined method `first' for #<RSpec::Mocks::MessageExpectation:0x104c99910>
 # ./spec/controllers/topics_controller_spec.rb:41

Очевидно, это похоже на вызов метода "first". Я понимаю, что это немного избыточно в данном конкретном случае, поэтому я мог бы удалить его, но вместо того, чтобы взломать дыру в моих знаниях, я хотел бы научиться делать это правильно (для этого сценария).

Может кто-нибудь помочь мне заполнить мою дыру?

Обновление:

Я добавил массив [@topic], как предлагалось в ответах, но теперь я получаю сообщение об ошибке:

  Failure/Error: put :update, :topic_slug => "some-slug", :topic => {}
       Mock "Topic_1001" received unexpected message :slug with (no args)

В отношении этого кода:

  def get_topic
    @topic = Topic.where(:slug => params[:topic_slug]).first
    @topic
  end

Параметры не могут быть изменены (по крайней мере, не тривиально). Буду признателен за дальнейшую помощь!

Ответы [ 2 ]

3 голосов
/ 11 августа 2011

Изменить эту строку

Topic.should_receive(:where).with("some-slug").and_return(@topic)

на эту

Topic.should_receive(:where).with("some-slug").and_return([@topic])

вы ожидаете массив, но возвращаете один элемент.

2 голосов
/ 11 августа 2011

stub_chain является запахом кода и должен рассматриваться как последнее средство. Он очень тесно связывает вашу спецификацию с деталями реализации, которые могут быть изменены с помощью рефакторинга.

Я бы порекомендовал что-то вроде этого:

Topic.should_receive(:with_slug).and_return(@topic)

Затем добавьте метод with_slug к Topic и все готово.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...