RSpec在发布请求之间保留实例变量

时间:2017-05-30 10:39:37

标签: ruby rspec factory-bot

在特定测试中,我想在我网站的某些订单中添加多个项目(package_sets)。

为了测试它,我按照以下方式进行测试

  context "with multiple package sets from different shops" do

    let(:package_sets) { FactoryGirl.create_list(:package_set, 3) }

    it "adds package sets to multiple orders" do
      package_sets.each do |package_set|
        post :create, {'package_set_id': package_set.id}
        expect_json(success: true)
      end
      expect(Order.count).to eq(3)
    end

  end

在现实世界中,每次调用post :create时,它都会将包集分配给不同的顺序;订单总数应为3。

在我的控制器中,我会在像这样的方法中记住订单

def order
   @order ||= cart_manager.order(shop: package_set.shop, call_api: false)
end

因为它有3个不同的请求,我希望测试能够在没有memoization的情况下重新加载这个方法,但是它会在@order请求之间保留post,这使得测试失败

你如何阻止这种情况?

2 个答案:

答案 0 :(得分:2)

这里发生的是RSpec不会在您的示例中创建新的控制器实例;你可以通过将一些逻辑泄漏到测试中来克服这个问题:

controller.instance_variable_set(:@order, nil)

对于这个特定的问题,可能会缩短代码,但您是否会考虑针对单个操作测试控制器?

package_set = FactoryGirl.create(:package_set)
expect do
  post :create, {'package_set_id': package_set.id }
end.to change(Order, :count).by(1)

答案 1 :(得分:0)

您可以在before - 块中重置@order变量:

describe Class do
    before(:each) do
        @order = Order.new()
    end

    context "with multiple package sets from different shops" do
        #...
    end
end