RSpec 在 post 个请求之间保留实例变量

RSpec keeps instance variable between post requests

在特定测试中,我想在我网站的某些订单中添加多个项目 (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 个不同的请求,所以我希望测试也能在没有记忆的情况下重新加载此方法,但它会在 post 请求之间保持 @order 记忆,这使得测试失败。

你如何防止这种情况发生?

这里发生的是 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)

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

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

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