Reputation: 4049
I have a truncation
database cleaning strategy, so not sure why else this is happening. Basically just doing a single feature spec to test that an order gets created appropriately.
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
The spec fails because @order creation depends on a @site
. Any thoughts on why the @site is being destroyed? Again I do have a truncation set up correctly:
# 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
Upvotes: 1
Views: 193
Reputation: 101811
A better way to test this altogether is to use the 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
This creates a count query before and after the block is evaluated. One thing you should bear in mind with .size
is that will return the length of the collection if it already has been loaded. Which is not a good thing here as you need a db count.
Naming your top level feature description "create successfully" is not a good idea. It does not describe what you are testing it would require you to creates two files to test for success and failure.
That controller is also just plain wrong.
def create
@order = Order.new(order_params)
if @order.save
redirect_to @order
else
render :new
end
end
@order.save if @order.valid?
is silly. .save
will validate the record and persist it if its valid. You really just want to check the return value of save to see if the record has actually been saved to the database. If orders is a nested record it should actually look like this as well:
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
Upvotes: 0