在功能规格达到POST控制器动作时删除在块之前创建的Rspec变量

问题描述 投票:1回答:1

我有一个truncation数据库清理策略,所以不确定为什么会这样。基本上,只需执行一个功能说明即可测试订单是否已正确创建。

require 'rails_helper'

describe "create successfully", type: :feature, js: true do
  before do
    @site = create(:site)
    visit "/orders"
    .... # various actions to build an order using the page's form
    puts ">>>>>"
    puts "site in before action: #{Site.all.size}"
    find("#checkoutModal #submit").click()
    sleep(1)
  end
  it "should create" do
    expect(Order.all.size).to equal(1)
  end
end

# controller action that #submit POSTs to

def create
  puts ">>>>>"
  puts "site in controller create: #{Site.all.size}"
  @order = Order.new(order_params)
  @order.save if @order.valid?
end

# puts output:
>>>>>
site in before action: 1
>>>>>
site in controller create: 0

该规范失败,因为@order的创建取决于@site。关于为什么@site被销毁有什么想法?同样,我确实设置了正确的截断:

# rails_helper.rb

Rspec.configure do |config|
  config.use_transactional_fixtures = false
  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each, js: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each, truncate: true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end
end



ruby-on-rails rspec capybara capybara-webkit database-cleaner
1个回答
0
投票

一种更好的测试方法是使用change匹配器:

Rspec.feature "Creating orders", js: true do

  let!(:site ) { create(:site) }

  def fill_in_and_submit_form
    visit "/orders"
    # ...
    fill_in "something", with: attributes[:something]
    find("#checkoutModal #submit").click()
  end

  context "with valid attributes" do
    let(:attributes){ attributes_for(:order) }
    it "creates an order" do
      expect do
        fill_in_and_submit_form
      end.to change(Order, :count).by(1)
    end
  end

  context "with invalid attributes" do
    let(:attributes) do
       {} # should be a hash with invalid attributes
    end
    it "does not create an order" do
      expect do
        fill_in_and_submit_form
      end.to_not change(Order, :count)
    end
  end
end

这将在计算块之前和之后创建计数查询。使用.size应该记住的一件事是,如果集合已经被加载,它将返回集合的长度。这不是一件好事,因为您需要数据库计数。

将顶级功能描述命名为“成功创建”不是一个好主意。它没有描述您要测试的内容,而是需要创建两个文件来测试成功和失败。

该控制器也完全是错误的。

def create
  @order = Order.new(order_params)
  if @order.save
    redirect_to @order
  else
    render :new
  end
end

@order.save if @order.valid?很傻。 .save将验证记录并将其保存(如果有效)。您确实只想检查save的返回值,以查看记录是否实际上已保存到数据库中。如果订单是嵌套记录,则它实际上也应该如下所示:

def create
  @site = Site.find(params[:site_id]) # you're not passing it through a hidden input are you?
  @order = @site.orders.new(order_params)
  if @order.save
    redirect_to @order
  else
    render :new
  end
end
© www.soinside.com 2019 - 2024. All rights reserved.