代码之家  ›  专栏  ›  技术社区  ›  mix-fGt

RSpec Capybara-请求测试。需要建议

  •  -1
  • mix-fGt  · 技术社区  · 9 年前

    有两件事我根本不懂。

    1) 第一个示例: 访问路径 -失败和 获取路径 -通过,为什么? 访问capybara并获取-rspec助手,对吗?

      describe "in the Users controller" do
       describe "visiting the users page as non-signed" do
         before { get users_path }
         #before { visit users_path }
         it { expect(response.status).to eql(302) }
         it { expect(response).to redirect_to(new_user_session_path) }
       end
       describe "visiting the user[:id = 1] profile page as non-signed" do
         before { get user_path(User.where(admin: true)) }
         #before { visit user_path(User.where(admin: true)) }
         it { expect(response.status).to eql(302) }
         it { expect(response).to redirect_to(new_user_session_path)  }
       end
     end
    

    具有 在此处获取路径 ->测试通过

    但是有了 访问此处的某个路径 ->

    enter image description here

    2) 第二个示例:

    作为普通用户登录后,不应该有像admin这样的菜单。 看起来像是 用户和管理员之间没有区别

      describe "as signed admin" do
        let(:admin) { create(:admin) }
        before do
          log_in admin
        end
        it { should have_link("Users", href: users_path)}
        it { should have_link("Orders", href: orders_path)}
        it { should have_link("Current Menu", href: products_path)}
        it { should_not have_link("Dashboard", href: new_order_path)}
      end
    
      describe "as signed user" do
        let(:user) { create(:user) }
          before do
            log_in user
          end
        it { should have_link("Profile", href: user_path(user))}
        it { should have_link("Dashboard", href: new_order_path)}
        it { should_not have_link("Users", href: users_path)}
        it { should_not have_link("Current Menu", href: products_path)}
      end
    
    
    include ApplicationHelper
    
    def log_in(user)
     visit root_path
     fill_in 'Email', with: user.email
     fill_in 'Password', with: user.password
     click_button 'Sign in'
    end
    def sign_up(user)
      visit new_user_registration_path
     fill_in 'Username', with: user.username
     fill_in 'Email', with: user.email
     fill_in 'Password', with: user.password
     fill_in 'Password confirmation', with: user.password
     click_button 'Sign up'
    end
    

    enter image description here

    编辑1

    我真的很喜欢……但我搞不懂……这有什么问题。。?

    let(:admin) { create(:admin) }
    let(:user) { create(:user) }
    
    factory :user do
      sequence(:username)  { |n| "Person #{n}" }
      sequence(:email)     { |n| "person_#{n}@example.com"}
      password              "qwerty"
      password_confirmation "qwerty"
    
      factory :admin do
       admin true
      end
    end
    

    和我的观点

    - if user_signed_in?
    %ul.nav.navbar-nav
      %li
        =link_to "Profile", current_user
      - if !current_user.admin?
        #if !current_user.try(:admin?)
        %li
          =link_to "Dashboard", new_order_path
        - if !Order.get_order_for_user(current_user).nil?
          %li
            %a{:href => order_path(Order.get_order_for_user current_user)} Order
      - else
        %li
          %a{:href => users_path} Users
        %li
          %a{:href => orders_path } Orders
        %li
          %a{:href => products_path } Current Menu
    %ul.nav.navbar-nav.navbar-right
      %li
        = link_to "Sign Out", destroy_user_session_path, :method =>  :delete
    it looks fine for me,but maybe i miss something...
    

    编辑2

    db/shcema的简短版本:

    create_table "users", force: true do |t|
        t.string   "email",                  default: "", null: false
        t.string   "encrypted_password",     default: "", null: false
        t.string   "reset_password_token"
        t.datetime "reset_password_sent_at"
        t.datetime "remember_created_at"
        t.integer  "sign_in_count",          default: 0,  null: false
        t.datetime "current_sign_in_at"
        t.datetime "last_sign_in_at"
        t.inet     "current_sign_in_ip"
        t.inet     "last_sign_in_ip"
        t.datetime "created_at",                          null: false
        t.datetime "updated_at",                          null: false
        t.string   "username"
        t.string   "avatar"
        t.boolean  "admin"
      end
    

    和我的用户模型:

     before_save :set_default_role
    
      private
      # Set first user as Admin
      def set_default_role
        if User.count == 0
          self.admin = true
        end
      end
    

    编辑3-最后一个!;)

    我保存我的beforesave:set_default_role

    但在我的测试中,我做到了:

      # User model -> before_save make first user admin.
      let(:admin) { create(:user) }
      let(:non_admin) { create(:user) }
      before do
        sign_up admin
        log_in non_admin
      end
    

    我知道这可能并不理想,但它很管用,这对我的专业水平来说很好。但如果有人有BP解决方案,我会注意到;)

    1 回复  |  直到 9 年前
        1
  •  3
  •   Thomas Walpole    9 年前

    1) 使用Capybara时,您使用 visit page ,当使用普通的rails集成测试(RSpec请求规范是其中的包装)时,您使用 get response -你不能像使用 参观 回答 在一起此外,在Capybara中,大多数驱动程序都不提供对请求响应代码以及页面是否重定向等内容的访问,因为它是为了从用户角度进行测试而设计的,这意味着只对浏览器中出现的内容进行回复。

    2) 从您的错误中可以看出,普通用户的行为与管理员用户完全相同,这可能是由一些事情引起的,具体取决于您在页面上实际执行的操作。最简单的解释是,在模型中或视图中的逻辑中,您对用户是否为管理员的条件检查没有正确实现。