【问题标题】:Rspec: Stubbing out a where statement in a controller testRspec:在控制器测试中删除 where 语句
【发布时间】:2012-10-15 18:35:50
【问题描述】:

我正在编写以下测试:

    let!(:city_areas) { FactoryGirl.create_list(:city_area, 30) }

    before {
        @city_areas = mock_model(CityArea)
        CityArea.should_receive(:where).and_return(city_areas)
    }

    it 'should assign the proper value to city areas variable' do
        get :get_edit_and_update_vars
        assigns(:city_areas).should eq(city_areas.order("name ASC"))
    end

测试以下方法:

def get_edit_and_update_vars
    @city_areas = CityArea.where("city_id = '#{@bar.city_id}'").order("name ASC").all
end  

但是,它失败了,说没有用于 nil:NilClass 的方法 'city_id',这让我相信它仍在尝试使用实例变量 @bar。

我如何正确地删除这个 where 语句以防止这种情况发生?

【问题讨论】:

    标签: testing rspec controller


    【解决方案1】:

    为什么你在做@city_areas = mock_model(CityArea) 然后你就再也不用@city_areas了?

    我会这样测试:

    在模型 CityArea 中为此创建一个命名范围: where("city_id = '#{@bar.city_id}'").order("name ASC")

    然后在你的控制器规范中你做

    describe 'GET get_edit_and_update_vars' do
      before(:each) do
        @areas = mock('areas')
      end
    
      it 'gets the areas' do
        CityArea.should_receive(:your_scope).once.and_return(@areas)
        get :get_edit_and_update_vars
      end
    
      it 'assign the proper value to city areas variable' do
        CityArea.stub!(:your_scope => @areas)
        get :get_edit_and_update_vars
        assigns(:city_areas).should eq(ordered)
      end
    end
    

    您还应该在模型规范中为该新范围创建规范

    只是一个提示,你不应该在 before 块中使用 should_receive(...) ,使用存根!在之前并在你想测试调用该方法时使用 should_receive

    另外,你不应该在测试控制器时使用 factorygirl,你应该总是模拟模型,模型可以在模型规范上测试

    【讨论】:

    • 是的,你的解决方案最终变得更干净了。感谢您的帮助!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多