Переменная Rspe c, созданная до удаления блока, к моменту, когда функция spe c достигает действия контроллера POSTed - PullRequest
1 голос
/ 15 марта 2020

У меня есть стратегия очистки базы данных truncation, поэтому я не уверен, почему это происходит. В основном, просто выполняем одну особенность spe c для проверки правильности создания ордера.

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

Spe c завершается ошибкой, поскольку создание @order зависит от @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



1 Ответ

0 голосов
/ 16 марта 2020

Лучший способ проверить это в целом - использовать change matcher:

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? is глупо. .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
...