简体   繁体   English

RSpec测试控制器操作创建不影响测试数据库

[英]RSpec test controller action create not affect test database

I have controller Categories which have action create: 我有创建动作的控制器类别:

def create
    @category = Category.new(category_params)
    respond_to do |format|
      if @category.save
        format.html { redirect_to @category, notice: 'Category was successfully created.' }
        format.json { render :show, status: :created, location: @category }
      else
        format.html { render :new }
        format.json { render json: @category.errors, status: :unprocessable_entity }
      end
    end
  end


 def category_params
   params.require(:category).permit(:name, :user_id)
 end

I need to test it by using RSpec. 我需要使用RSpec对其进行测试。 I wrote test: 我写了测试:

before(:each) do
    @user = create(:user)
    sign_in @user
  end

describe 'POST #create' do
    it 'creates category' do
      expect do
        post :create, params: {
          category: attributes_for(:category, user_id: @user.id)
        }
      end.to change { Category.count }.by(1) and
        redirect_to Category.last && have_http_status(200) and
        render_template('show')
    end
  end

When I run 当我跑步

$ bundle exec rspec $ bundle exec rspec

it output 它输出

Finished in 0.55119 seconds (files took 7.36 seconds to load) 2 examples, 0 failures 在0.55119秒内完成(文件花费了7.36秒加载时间)2个示例,0个失败

But when I come to 但是当我来到

rails c test Rails C测试

and try to output Cateroy.all or Category.first it show me that database is empty. 并尝试输出Cateroy.all或Category.First,它向我显示数据库为空。 Also I tried to check database via pgadmin and it is clear. 我也尝试通过pgadmin检查数据库,这很明显。

But I don't understand why it is clear after it successfull pass tests. 但是我不明白为什么在通过测试后就很清楚了。 I don't use gem 'database_cleaner' Also I can provide my last test logs: 我不使用gem'database_cleaner'也可以提供我的最后一个测试日志:

Completed 200 OK in 139ms (Views: 44.3ms | ActiveRecord: 4.5ms)
  [1m[35m (0.1ms)[0m  [1m[31mROLLBACK[0m
  [1m[35m (0.1ms)[0m  [1m[35mBEGIN[0m
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[36mUser Exists (0.2ms)[0m  [1m[34mSELECT  1 AS one FROM "users" WHERE "users"."email" = $1 LIMIT $2[0m  [["email", "roxane@bartoletti.org"], ["LIMIT", 1]]
  [1m[35mSQL (0.3ms)[0m  [1m[32mINSERT INTO "users" ("email", "encrypted_password", "confirmed_at", "created_at", "updated_at") VALUES ($1, $2, $3, $4, $5) RETURNING "id"[0m  [["email", "roxane@bartoletti.org"], ["encrypted_password", "$2a$04$8uzV2Wd4I7iOHvywVl3CUOK..eSLgSOwjYL31Fo6bu6wR.k4YPDVS"], ["confirmed_at", "2018-01-11 00:00:00"], ["created_at", "2018-01-11 16:35:24.255470"], ["updated_at", "2018-01-11 16:35:24.255470"]]
  [1m[35m (0.1ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
  [1m[35m (0.3ms)[0m  [1m[34mSELECT COUNT(*) FROM "categories"[0m
Processing by CategoriesController#create as HTML
  Parameters: {"category"=>{"name"=>"Amani Rogahn", "user_id"=>"4"}}
  [1m[36mUser Load (0.3ms)[0m  [1m[34mSELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2[0m  [["id", 4], ["LIMIT", 1]]
  [1m[35m (0.1ms)[0m  [1m[35mSAVEPOINT active_record_1[0m
  [1m[36mCategory Exists (0.3ms)[0m  [1m[34mSELECT  1 AS one FROM "categories" WHERE ("categories"."id" IS NOT NULL) AND "categories"."slug" = $1 LIMIT $2[0m  [["slug", "amani-rogahn"], ["LIMIT", 1]]
  [1m[36mUser Load (0.2ms)[0m  [1m[34mSELECT  "users".* FROM "users" WHERE "users"."id" = $1 LIMIT $2[0m  [["id", 4], ["LIMIT", 1]]
  [1m[35mSQL (0.3ms)[0m  [1m[32mINSERT INTO "categories" ("name", "user_id", "created_at", "updated_at", "slug") VALUES ($1, $2, $3, $4, $5) RETURNING "id"[0m  [["name", "Amani Rogahn"], ["user_id", 4], ["created_at", "2018-01-11 16:35:24.564081"], ["updated_at", "2018-01-11 16:35:24.564081"], ["slug", "amani-rogahn"]]
  [1m[35m (0.1ms)[0m  [1m[35mRELEASE SAVEPOINT active_record_1[0m
Redirected to http://test.host/en/categories/amani-rogahn
Completed 302 Found in 9ms (ActiveRecord: 1.4ms)
  [1m[35m (0.2ms)[0m  [1m[34mSELECT COUNT(*) FROM "categories"[0m
  [1m[36mCategory Load (0.2ms)[0m  [1m[34mSELECT  "categories".* FROM "categories" ORDER BY "categories"."id" DESC LIMIT $1[0m  [["LIMIT", 1]]
  [1m[35m (0.1ms)[0m  [1m[31mROLLBACK[0m

Here is my rails_helper.rb 这是我的rails_helper.rb

require 'support/factory_bot'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require File.expand_path('../../config/environment', __FILE__)
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
ActiveRecord::Migration.maintain_test_schema!
RSpec.configure do |config|
  config.fixture_path = "#{::Rails.root}/spec/fixtures"
  config.use_transactional_fixtures = true
  config.infer_spec_type_from_file_location!
  config.filter_rails_from_backtrace!
  config.include Devise::Test::ControllerHelpers, type: :controller
end

Here is my spec_helper.rb 这是我的spec_helper.rb

RSpec.configure do |config|
  config.expect_with :rspec do |expectations|
    expectations.include_chain_clauses_in_custom_matcher_descriptions = true
  end
  config.mock_with :rspec do |mocks|
  end
  config.shared_context_metadata_behavior = :apply_to_host_groups
=begin
  config.filter_run_when_matching :focus
  config.example_status_persistence_file_path = "spec/examples.txt"
  config.disable_monkey_patching!
  if config.files_to_run.one?
    config.default_formatter = "doc"
  end
  config.profile_examples = 10
  config.order = :random
  Kernel.srand config.seed
=end
end

Please help me to understand why this test not affect on test database and how to change this situation. 请帮助我了解为什么此测试不会影响测试数据库以及如何更改这种情况。

It's because you have this line: 这是因为您有以下行:

config.use_transactional_fixtures = true

The name of this setting is a bit misleading. 此设置的名称有点误导。 What it really means in Rails is "run every test method within a transaction." 在Rails中,真正的含义是“运行事务中的每种测试方法”。 In the context of rspec-rails, it means "run every example within a transaction." 在rspec-rails的上下文中,它的意思是“运行事务中的每个示例”。

The idea is to start each example with a clean database, create whatever data is necessary for that example, and then remove that data by simply rolling back the transaction at the end of the example. 这个想法是从一个干净的数据库开始每个示例,创建该示例所需的任何数据,然后通过在示例结束时简单地回滚事务来删除该数据。

See: https://relishapp.com/rspec/rspec-rails/docs/transactions 请参阅: https//relishapp.com/rspec/rspec-rails/docs/transactions

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM