2010-03-31 3 views
10

У меня есть две модели:RSpec, гася вложенными методы ресурсов

class Solution < ActiveRecord::Base 
    belongs_to :owner, :class_name => "User", :foreign_key => :user_id 
end 

class User < ActiveRecord::Base 
    has_many :solutions 
end 

и я гнездовых решений в пользователей, как это:

ActionController::Routing::Routes.draw do |map| 
    map.resources :users, :has_many => :solutions 
end 

и, наконец, вот действие я "м пытается чертежу :

class SolutionsController < ApplicationController 
    before_filter :load_user 

    def show 
    if(@user) 
     @solution = @user.solutions.find(params[:id]) 
    else 
     @solution = Solution.find(params[:id]) 
    end 
    end 

    private 

    def load_user 
    @user = User.find(params[:user_id]) unless params[:user_id].nil? 
    end 
end 

Мой вопрос, как, черт возьми, я Spec @user.solutions.find(params[:id])

Вот мой текущий спектр:

describe SolutionsController do 

    before(:each) do 
    @user = Factory.create(:user) 
    @solution = Factory.create(:solution) 
    end 

    describe "GET Show," do 

    before(:each) do 
     Solution.stub!(:find).with(@solution.id.to_s).and_return(@solution) 
     User.stub!(:find).with(@user.id.to_s).and_return(@user) 
    end 

    context "when looking at a solution through a user's profile" do 

     it "should find the specified solution" do 
     Solution.should_receive(:find).with(@solution.id.to_s).and_return(@solution) 
     get :show, :user_id => @user.id, :id => @solution.id 
     end 
    end 
    end 

Но что получает мне следующую ошибку:

1)Spec::Mocks::MockExpectationError in 'SolutionsController GET Show, when looking at a solution through a user's profile should find the specified solution' 
<Solution(id: integer, title: string, created_at: datetime, updated_at: datetime, software_file_name: string, software_content_type: string, software_file_size: string, language: string, price: string, software_updated_at: datetime, description: text, user_id: integer) (class)> received :find with unexpected arguments 
    expected: ("6") 
    got: ("6", {:group=>nil, :having=>nil, :limit=>nil, :offset=>nil, :joins=>nil, :include=>nil, :select=>nil, :readonly=>nil, :conditions=>"\"solutions\".user_id = 34"}) 

Может кто-нибудь помочь мне с тем, как я могу окурок @user.solutions.new(params[:id])?

ответ

25

Похоже, я нашел свой собственный ответ, но я собираюсь опубликовать его здесь, так как я не могу найти много об этом в сети.

RSpec имеет метод, называемый stub_chain: http://apidock.com/rspec/Spec/Mocks/Methods/stub_chain

, что делает его легко окурок метод, как:

@solution = @user.solutions.find(params[:id]) 

делая это:

@user.stub_chain(:solutions, :find).with(@solution.id.to_s).and_return(@solution) 

Итак, я могу написать RSpec следующим образом:

it "should find the specified solution" do 
    @user.solutions.should_receive(:find).with(@solution.id.to_s).and_return(@solution) 
    get :show, :user_id => @user.id, :id => @solution.id 
end 

И мой spec проходит. Тем не менее, я все еще участвую здесь, поэтому, если кто-то думает, что мое решение здесь нехорошо, пожалуйста, не стесняйтесь комментировать это, и я стараюсь понять его полностью.

Джо

+0

Очень полезно, спасибо. – zetetic

+0

Ваше приветствие, просто проголосуйте за ответы, пожалуйста! – TheDelChop

7

С новым синтаксисом RSpec, вы окурок церь так

allow(@user).to receive_message_chain(:solutions, :find) 
# or 
allow_any_instance_of(User).to receive_message_chain(:solutions, :find) 
Смежные вопросы