2013-04-23 3 views
1

그래서 여기에 관해서는 몇 가지 질문을 보았습니다.하지만 내 문제가 무엇인지 파악하는 데 도움이 될만큼 충분히 가까이 있지 않았습니다. 그래서 내가 잘못하고있는 것에 대한 도움이 될 것입니다. 감사합니다 ... 들으 (난 내가 특히 도움이 될 것입니다 자신의 예에서 이탈 한 방법에 대한 정보를 원하시면 그래서 마이클 하틀의 튜토리얼을 다음거야)Rspec 테스트가 비참하게 실패했습니다.

I'm throwing the following 2 errors: 

Failures: 

    1) Authentication authorization as wrong user submitting a PUT request to the Users#update action 
Failure/Error: before { put user_path(wrong_user) } 
NoMethodError: 
    undefined method `put' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_3::Nested_2::Nested_2:0x007f8943728688> 
# ./spec/features/authentication_pages_spec.rb:78:in `block (5 levels) in <top (required)>' 

2) Authentication authorization for non-signed-in users in the Users controller submitting to the update action 
Failure/Error: before { put user_path(user) } 
NoMethodError: 
    undefined method `put' for #<RSpec::Core::ExampleGroup::Nested_1::Nested_3::Nested_1::Nested_1::Nested_2:0x007f8944a85ff0> 
# ./spec/features/authentication_pages_spec.rb:61:in `block (6 levels) in <top (required)>' 

Finished in 3.06 seconds 
56 examples, 2 failures 

Failed examples: 

rspec ./spec/features/authentication_pages_spec.rb:79 # Authentication authorization as  wrong user submitting a PUT request to the Users#update action 
rspec ./spec/features/authentication_pages_spec.rb:62 # Authentication authorization for non- signed-in users in the Users controller submitting to the update action 

다음과 같이 내 코드는 다음과 같습니다

사양/기능 /authentication_pages_spec.rb

require 'spec_helper' 

describe "Authentication" do 

    subject { page } 

    # FOR STATIC SIGN IN PAGE 
    describe "signin page" do 
    before { visit signin_path } 

    it { should have_selector('h1', text: 'Sign in') } 
    it { should have_title('Sign in') } 
    end 

    # FOR SIGNIN PROCESS 
    describe "signin" do 
    before { visit signin_path } 

    describe "with invalid information" do 
     before { click_button "Sign in" } 

     it { should have_title('Sign in') } 
     it { should have_error_message } 

     describe "after visiting another page" do 
     before { click_link "Home" } 
     it { should_not have_error_message } 
     end 
    end 

    describe "with valid information" do 
     let(:user) { FactoryGirl.create(:user) } 
     before { sign_in user } 

     it { should have_title(user.name) } 
     it { should have_link('Profile',  href: user_path(user)) } 
     it { should have_link('Sign out', href: signout_path) } 
     it { should have_link('Settings', href: edit_user_path(user)) } 
     it { should_not have_link('Sign in', href: signin_path) } 

     describe "followed by signout" do 
     before { click_link "Sign out" } 
     it { should have_link('Sign in') } 
     end 
    end 
    end 

    # FOR AUTHORIZING WHICH ACCOUNTS CAN DO WHAT 
    describe "authorization" do 

    describe "for non-signed-in users" do 
     let(:user) { FactoryGirl.create(:user) } 

     describe "in the Users controller" do 
     describe "visiting the edit page" do 
      before { visit edit_user_path(user) } 
      it { should have_title('Sign in') } 
     end 

     describe "submitting to the update action" do 
      before { put user_path(user) } 
      specify { response.should redirect_to(signin_path) } 
     end 
     end 
    end 

    describe "as wrong user" do 
     let(:user) { FactoryGirl.create(:user) } 
     let(:wrong_user) { FactoryGirl.create(:user, email: "[email protected]") } 
     before { sign_in user } 

     describe "visiting Users#edit page" do 
     before { visit edit_user_path(wrong_user) } 
     it { should_not have_selector('title', text: full_title('Edit user')) } 
     end 

     describe "submitting a PUT request to the Users#update action" do 
     before { put user_path(wrong_user) } 
     specify { response.should redirect_to(root_path) } 
     end 
    end 

    end 
end 

내 사양/기능/user_pages_spec.rb

require 'spec_helper' 

describe "User pages" do 

    subject { page } 

    # TESTING STATIC PROFILE PAGE 
    describe "profile page" do 
    let(:user) { FactoryGirl.create(:user) } # Code to make a user variable 
    before { visit user_path(user) } 

    it { should have_selector('h1', text: user.name) } 
    it { should have_title(user.name) } 
    end 

    # TESTING STATIC SIGNUP PAGE 
    describe "signup page" do 
    before { visit signup_path } 

    it { should have_selector('h1', text: 'Sign up') } 
    it { should have_title("Sign up") } 
    end 

    # TESTING SIGN UP PROCESS 
    describe "signup" do 
    before { visit signup_path } 

    let(:submit) { "Create my account" } 

    describe "with invalid information" do 
     it "should not create a user" do 
     expect { click_button submit }.not_to change(User, :count) 
     end 

     describe "after submission" do 
     before { click_button submit } 

     it { should have_title('Sign up') } 
     it { should have_content('error') } 
     end 
    end 

    describe "with valid information" do 
     before do 
     fill_in "Name",   with: "Example User" 
     fill_in "Email",  with: "[email protected]" 
     fill_in "Password",  with: "foobar" 
     fill_in "Confirmation", with: "foobar" 
     end 

     it "should create a user" do 
     expect { click_button submit }.to change(User, :count).by(1) 
     end 

     describe "after saving the user" do 
     before { click_button submit } 
     let(:user) { User.find_by_email('[email protected]') } 

     it { should have_title(user.name) } 
     it { should have_selector('div.alert.alert-success', text: 'Welcome') } 
     it { should have_link('Sign out') } 
     end 

    end 
    end 

    # TESTING EDITING FUNCTIONALITY 
    describe "edit" do 
    let(:user) { FactoryGirl.create(:user) } 
    before do 
     sign_in user 
     visit edit_user_path(user) 
    end 

    describe "page" do 
     it { should have_selector('h1', text: "Update your profile") } 
     it { should have_title("Edit user") } 
     # it { should have_link('change', href: 'http://gravatar.com/emails') } 
     # needed if using gravatar 
    end 

    describe "with invalid information" do 
     before { click_button "Save changes" } 

     it { should have_content('error') } 
    end 

    describe "with valid information" do 
     let(:new_name) { "New Name" } 
     let(:new_email) { "[email protected]" } 
     before do 
     fill_in "Name",    with: new_name 
     fill_in "Email",   with: new_email 
     fill_in "Password",   with: user.password 
     fill_in "Confirm Password", with: user.password 
     click_button "Save changes" 
     end 

     it { should have_title(new_name) } 
     it { should have_selector('div.alert.alert-success') } 
     it { should have_link('Sign out', href: signout_path) } 
     specify { user.reload.name.should == new_name } 
     specify { user.reload.email.should == new_email } 
    end 

    end 

end 

내 사양/지원/utilities.rb

include ApplicationHelper 

RSpec::Matchers.define :have_error_message do |message| 
    match do |page| 
    page.has_selector?('div.alert.alert-error', text: 'Invalid') 
    end 
end 

def sign_in(user) 
    visit signin_path 
    fill_in "Email", with: user.email 
    fill_in "Password", with: user.password 
    click_button "Sign in" 
    # Sign in when not using Capybara. 
    # cookies[:remember_token] = user.remember_token 
end 

내 컨트롤러/users_controller.rb

class UsersController < ApplicationController 
    before_filter :signed_in_user, only: [:edit, :update] 


    def new 
    @user = User.new 
    end 

    def show 
    @user = User.find(params[:id]) 
    end 

    def create 
    @user = User.new(params[:user]) 
    if @user.save 
     sign_in @user 
     flash[:success] = "Welcome to Authentication App..." 
     redirect_to @user 
    else 
     render 'new' 
    end 
    end 

    def edit 
    @user = User.find(params[:id]) 
    end 

    def update 
    @user = User.find(params[:id]) 
    if @user.update_attributes(params[:user]) 
     sign_in @user 
     flash[:success] = "Profile updated" 
     redirect_to @user 
    else 
     render 'edit' 
    end 
    end 

    def destroy 
    User.find(params[:id]).destroy 
    flash[:success] = "User destroyed" 
    redirect_to users_path 
    end 

    private 

    def signed_in_user 
     redirect_to signin_url, notice: "Please sign in." unless signed_in? 
    end 

end 

& 마지막으로 내보기/users/edit.html.erb

<% provide(:title, "Edit user") %> 
<h1>Update your profile</h1> 

<div class="row"> 
    <div class="span6 offset3"> 
    <%= form_for(@user) do |f| %> 
     <%= render 'shared/error_messages' %> 

     <%= f.label :name %> 
     <%= f.text_field :name %> 

     <%= f.label :email %> 
     <%= f.text_field :email %> 

     <%= f.label :password %> 
     <%= f.password_field :password %> 

     <%= f.label :password_confirmation, "Confirm Password" %> 
     <%= f.password_field :password_confirmation %> 

     <%= f.submit "Save changes", class: "btn btn-large btn-primary" %> 
    <% end %> 

    </div> 
</div> 

올바른 수정에 대한 모든 도움을 주시면 감사하겠습니다. 덕분에

답변

0

레일 튜토리얼을 따르려면 Capybara 버전을 1.1.2로 다운 그레이드하고 spec/requests 디렉토리로 스펙을 이동해야합니다. 당신의 Gemfile 업데이트 :

당신이 카피 바라 2.0을 사용하려는 경우
gem 'capybara', '1.1.2' 

, 내가이 글을 읽는 것이 좋습니다 :

http://alindeman.github.io/2012/11/11/rspec-rails-and-capybara-2.0-what-you-need-to-know.html

+0

thanks 남자 - 엉덩이에 통증처럼 보입니다 ... 그래서 기본적으로 다시 가서 사양/요청 capybara되지 않은 모든 테스트를 넣어야만 ??? 그러나 capybara 테스트를/features 폴더에 보관 하시겠습니까 ?? (나는 새로운 2+ 카피 바라와 붙어 있습니다 - 그 링크는 매우 도움이되었습니다) – BB500

+0

Michael Hartl의 튜토리얼을 따르고 있다면 파일을'spec/features'에서'spec/requests'로 옮기십시오. GitHub의 [sample_app] (https://github.com/railstutorial/sample_app_2nd_ed)를 살펴보십시오. –

+0

다른 사람이이 특정 오류가있는 문제가있는 경우 ... 나는이 사람들의 도움으로 도움을받을 수있었습니다 ... spec/요청/폴더에 중복 된 authentication_pages_spec.rb를 다시 만들면 ... strip [update action do do] 테스트를 제출하고 새로 복사 된 파일에 배치하십시오. (그러나 let (: user) {FactoryGirl.create (: user)}를 추가하는 것을 잊지 마십시오. – BB500

1

put, get, post, delete 그리고 이러한 기능 테스트는 기능 테스트에서 사용할 수 없습니다.

버튼 테스트/ajax/etc ...를 통해 put을 "제출"해야하며, 기능 테스트를 작성할 때 컨트롤러 테스트와 같이 컨트롤러에 게시하지 않아야합니다.

+0

감사합니다. kwon -이 테스트를 새 디렉토리에 넣어야합니까? 아니면 올바른 방향으로 나를 가리킬 수 있습니까? 죄송합니다 - rspec & tdd에 꽤 새로운 ... – BB500

+0

즉, 나는 단지 "업데이트 조치 제출"에 대한 설명을 모두 삭제할 수 있습니다. 분명히 테스트 할 수 있지만 최선의 생각이 아닐 것이라고 생각합니다 ... thx – BB500

1

문제는 다음과 같습니다 당신은 기능 테스트로 요청 (capybara) 시험을 엉망으로. 당신은 응용 프로그램과 통신, put, get, postdelete를 HTTP 동사를 사용할 필요가 있기 때문에 같은

require 'spec_helper' 

describe "Website access" do 
    context "when I am a registered user" do 
    it "should let me in" do 
     page.fill_in 'Email', with: '[email protected]' 
     page.fill_in 'Password', with: 'mydearluke' 
     page.click_link 'Let me in' 

     page.should have_content('Welcome, cheif!') 
    end 
    end 

    context "when I am not a registered user" do 
    it "should not let me in" do 
     page.fill_in 'Email', with: '[email protected]' 
     page.fill_in 'Password', with: 'wormsarmageddon' 
     page.click_link 'Let me in' 

     page.should have_content('Incorrect credentials!') 
    end 
    end  
end 

기능 테스트와 같이 사용자 단계를 설명한다 capybara에서

는 낮은 수준에서 작동하면 다시 테스트 해. 여기에서 주목해야 할

require 'spec_helper' 

describe SessionsController do 
    context "when I am registered user" do 
    it "should let me in" do 
     post :create, email: '[email protected]', password: 'mydearluke' 

     response.should be_success 
    end 
    end 

    context "when I am not a registered user" do 
    it "should not let me in" do 
     post :create, email: '[email protected]', password: 'wormsarmageddon' 

     response.should_not be_success 
    end 
    end  
end 

몇 가지 : 나는 putpost을하지 사용하고

  1. .
  2. capybara 테스트와 같은 일반 영어 디자인과 달리 컨트롤러 이름을 describe 블록으로 지정합니다.
  3. 기능 테스트는 SessionController이 다른 사용자 자격 증명에 얼마나 정확하게 응답해야 하는지를 지정합니다 (좋은 사용자에 대한 세션을 생성하고 등록되지 않은 사용자에 대해 비명을 지어야 함). 당신이 뭘 하려는지

요청 (카피 바라) 테스트에서 기능 테스트에서 동사를 사용하는 것입니다. 이것은 잘못된 것입니다.

정리 해보 :

  1. 사용 visitclick_link/click_buttoncapybara에서 테스트.
  2. 기능 테스트에서 HTTP 동사 (put, get, post, delete)를 사용하십시오.
  3. 사용자 인증을 위해 devise 보석을 사용하십시오.
+0

나는 그 사람에게 감사합니다. 이것은 매우 도움이되었습니다. (분명히 나는 ​​당신의 대답을 upvote하기에 충분한 점수 또는 뭔가를 가지고 있지 않다) – BB500

관련 문제