2012-02-12 39 views
5

Tôi có các kiểu: Post and User (Devise). Tôi đang kiểm tra bộ điều khiển Post.Kiểm tra bộ điều khiển với RSpec, Devise, Factory Girl

describe "If user sign_in" do 

    before(:all){ 
    @user = Factory(:user) 
    } 

    it "should get new" do 
    sign_in @user 
    get 'new' 
    response.should be_success 
    response.should render_template('posts/new') 
    end 

    it "should create post" do 
    sign_in @user 
    post 'create', :post => Factory(:post) 
    response.should redirect_to(post_path(:post)) 
    end 
end 

Nhưng cuộc thử nghiệm thứ hai thất bại:

Failure/Error: post 'create', :post => Factory(:post) ActiveRecord::RecordInvalid: Validation failed: Email has already been taken, Email has already been taken, Username has already been taken

Làm thế nào để sửa lỗi này?

Trả lời

7

Bạn cần một công cụ để làm sạch cơ sở dữ liệu giữa các lần kiểm tra. Bởi vì bạn sẽ có thể chạy từng thử nghiệm với một cơ sở dữ liệu sạch. Tôi đang sử dụng database_cleaner, nó khá là một viên ngọc nổi tiếng và nó hoạt động thực sự tốt. Thật dễ dàng để thiết lập quá. Ví dụ từ README (liên quan đến RSpec):

RSpec.configure do |config| 

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

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

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

end 
+3

Khi tôi bao gồm mã của bạn trong spec_helper. Tôi gặp lỗi Lỗi/Lỗi: Không thể tìm thấy dòng khớp từ backtrace ActiveRecord :: StatementInvalid: SQLite3 :: SQLException: không thể bắt đầu giao dịch trong một giao dịch: bắt đầu giao dịch – Mike

+0

bạn không cần một gem khác. – coneybeare

+3

Tôi tìm thấy giải pháp ngoại lệ SQLite là xóa 'clean_with (: truncation)' và thay đổi chiến lược hoàn toàn thành 'DatabaseCleaner.strategy =: truncation' – Dan

9

Bạn không cần một loại đá quý khác cho việc này. FactoryGirl đã xây dựng những người trợ giúp năng động cho việc này. Tôi khuyên bạn nên xem đoạn ngắn Railscast về điều này. Đây là đoạn trích hoạt động:

FactoryGirl.define do 
    factory :user do 
    sequence(:username) { |n| "foo#{n}" } 
    password "foobar" 
    email { "#{username}@example.com" } 
+1

hmmm, một liên kết đến nội dung trả phí ... dường như không giống nhất hữu ích của câu trả lời ... – botbot

+18

Nếu bạn là một nhà phát triển đường ray và không sử dụng Railcast, thì bạn đang làm sai. – coneybeare

+0

nhưng nếu bạn là nhà phát triển TRUE Rails, thì bạn nên liên kết với nội dung miễn phí trước và sau đó đề xuất nội dung trả phí – Aleks

Các vấn đề liên quan