失败的人创造规范

时间:2014-10-31 18:39:22

标签: ruby-on-rails rspec devise capybara

我已经编写了一个集成测试来在我的Rails应用程序中创建一个新人。注册表(使用Devise)在开发和生产中都很好用,但我也希望有一个规范。

然而规格失败了,我看到了一些奇怪的行为。这个规格是唯一一个失败的规则 - 所有其他规则都通过了。

我在日志中注意到dev / prod中的日志显示

Processing by Devise::RegistrationsController#create

并且传递的参数是

Parameters: {"utf8"=>"✓", "authenticity_token"=>"sRvErzoB/SwegGe/hNRp3J4zJ7i9Rk5yVY0sHymgW7M=", "person"=>{"first_name"=>"Warbling", "last_name"=>"Goose", "email"=>"goose@test.co", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up!"}

另一方面,当运行规范时,测试日志显示

Processing by Devise::RegistrationsController#new as HTML

并且传递的参数是

Parameters: {"person"=>{"first_name"=>"Warbling", "last_name"=>"Goose", "email"=>"goose@test.co", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up!"}

有趣的是,我没有看到在测试日志中传递了authenticity_token吗?

这是我的Gemfile:

source 'https://rubygems.org'

group :development, :test do
  gem 'factory_girl_rails', '4.5.0'
  gem 'shoulda-matchers', require: false
  gem 'rspec-rails', '2.99.0'
  gem 'capybara', '2.4.4'
  gem 'launchy'
  gem 'pry'
  gem 'faker'
  gem 'populator'
end

group :test do
  gem 'database_cleaner'
  gem 'email_spec'
  gem 'pry-byebug'
end

group :development do
  gem 'guard-rspec', require: false
  gem 'spring', '1.1.3'
  gem 'rails_layout'
end

group :doc do
  gem 'sdoc', '~> 0.4.0'
end

gem 'rails', '4.1.6'
gem 'slim-rails'
gem 'pg'
gem 'sass-rails', '~> 4.0.3'
gem 'uglifier', '>= 1.3.0'
gem 'coffee-rails', '~> 4.0.0'
gem 'jquery-rails'
gem 'turbolinks'
gem 'jbuilder', '2.2.4'
gem 'bootstrap-sass'
gem 'figaro', '1.0.0'
gem 'simple_form', '~> 3.1.0.rc2'
gem 'devise', '3.4.1'
gem 'font-awesome-rails'

这是我的spec_helper.rb:

ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'shoulda/matchers'
require 'faker'
require 'email_spec'

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

ActiveRecord::Migration.maintain_test_schema!

RSpec.configure do |config|
  config.include Devise::TestHelpers, :type => :controller

  # Include Factory Girl syntax to simplify calls to factories
  config.include FactoryGirl::Syntax::Methods
  config.include EmailSpec::Helpers
  config.include EmailSpec::Matchers

  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  config.use_transactional_fixtures = false

  config.infer_base_class_for_anonymous_controllers = false

  config.order = "random"

  config.infer_spec_type_from_file_location!

  config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

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

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

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

  config.before(:suite) do
    require "#{Rails.root}/db/seeds.rb"
  end
end

规范本身:

require 'spec_helper'
require 'capybara/rspec'

feature 'Person creates an account' do

  scenario 'Successfully' do
    visit root_path
    click_link 'Sign up'
    fill_in_with_valid_data
    expect { click_button 'Sign up!' }.to change(Person, :count).by(1)
    email = open_email('goose@test.co')
    click_first_link_in_email
    expect(page).to have_content( "Your email has been confirmed.")
  end

  def fill_in_with_valid_data(attributes = {})
    fill_in 'person_first_name', :with => 'Warbling'
    fill_in 'person_last_name', :with => 'Goose'
    fill_in 'person_email', :with => 'goose@test.co'
    fill_in 'person_password', :with => 'password'
    fill_in 'person_password_confirmation', :with => 'password'
  end
end

规范的日志输出:

Started GET "/people/sign_in" for 127.0.0.1 at 2014-10-31 14:31:35 -0400
Processing by Devise::SessionsController#new as HTML
  Rendered devise/sessions/new.html.slim within layouts/application (31.2ms)
Completed 200 OK in 105ms (Views: 87.7ms | ActiveRecord: 2.1ms)
Started GET "/people/sign_up" for 127.0.0.1 at 2014-10-31 14:31:35 -0400
Processing by Devise::RegistrationsController#new as HTML
  Rendered devise/registrations/new.html.slim within layouts/application (8.8ms)
Completed 200 OK in 12ms (Views: 11.3ms | ActiveRecord: 0.0ms)
   (0.7ms)  SELECT COUNT(*) FROM "people"
Started GET "/people/sign_up?person[first_name]=Warbling&person[last_name]=Goose&person[email]=goose%40test.co&person[password]=[FILTERED]&person[password_confirmation]=[FILTERED]&commit=Sign+up%21" for 127.0.0.1 at 2014-10-31 14:31:35 -0400
Processing by Devise::RegistrationsController#new as HTML
  Parameters: {"person"=>{"first_name"=>"Warbling", "last_name"=>"Goose", "email"=>"goose@test.co", "password"=>"[FILTERED]", "password_confirmation"=>"[FILTERED]"}, "commit"=>"Sign up!"}
  Rendered devise/registrations/new.html.slim within layouts/application (1.7ms)
Completed 200 OK in 4ms (Views: 3.3ms | ActiveRecord: 0.0ms)
   (0.3ms)  SELECT COUNT(*) FROM "people"
   (0.1ms)  ROLLBACK

如果它有用,请注册表格:

= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
  .container
    = devise_error_messages!
    #signupbox.mainbox.col-md-6.col-md-offset-3.col-sm-8.col-sm-offset-2 style=("margin-top:50px")
      .panel.panel-info
        .panel-heading
          .panel-title Sign Up
          div style=("float:right; font-size: 80%; position: relative; top:-17px")
            = link_to "Sign in", new_person_session_path
        .panel-body style="padding-top:30px"
          form#signupform.form-horizontal role="form"
            .input-group style=("margin-bottom: 25px")
              span.input-group-addon
                i.fa.fa-user.fa-fw
              = f.input_field :first_name, placeholder: 'First name', :autofocus => true, class: 'login-username form-control'
            .input-group style=("margin-bottom: 25px")
              span.input-group-addon
                i.fa.fa-user.fa-fw
              = f.input_field :last_name, placeholder: 'Last name', class: 'login-username form-control'
            .input-group style=("margin-bottom: 25px")
              span.input-group-addon
                i.fa.fa-paper-plane.fa-fw
              = f.input_field :email, placeholder: 'Email address', class: 'login-email form-control'
            .input-group style=("margin-bottom: 25px")
              span.input-group-addon
                i.fa.fa-key.fa-fw
              = f.input_field :password, placeholder: 'Password', class: 'login-password form-control'
            .input-group style=("margin-bottom: 25px")
              span.input-group-addon
                i.fa.fa-key.fa-fw
              = f.input_field :password_confirmation, autocomplete: 'off', placeholder: 'Confirm your password', class: 'login-password-confirmation form-control'
            .form-group style="margin-top:10px"
              /! Button
              .col-sm-12.controls
                = f.submit 'Sign up!', :class => 'btn-login btn btn-success'

和rspec测试的输出:

rspec spec/features/person_signup_spec.rb 

Person creates an account
  Successfully (FAILED - 1)

Failures:

  1) Person creates an account Successfully
     Failure/Error: expect { click_button 'Sign up!' }.to change(Person, :count).by(1)
       count should have been changed by 1, but was changed by 0
     # ./spec/features/person_signup_spec.rb:13:in `block (2 levels) in <top (required)>'

Finished in 0.22247 seconds
1 example, 1 failure

Failed examples:

rspec ./spec/features/person_signup_spec.rb:9 # Person creates an account Successfully

1 个答案:

答案 0 :(得分:0)

看起来好像你在表单里面有一个表单。

= simple_form_for(resource, :as => resource_name, :url => registration_path(resource_name)) do |f|
  ...
  form#signupform.form-horizontal role="form"
  ...

您的规范可能使用第二个嵌入表单的默认操作。由于第二个嵌入表单上没有指定操作属性,因此默认为您在/people/sign_up上的当前页面,并且由于第二个表单上没有方法属性,因此默认为GET请求时表格已提交。

这就是为什么您看到表单作为GET请求提交到同一个注册页面。