我希望尽可能将测试保持为DRY,因此,它们看起来像这样:
describe "creating new product" do
subject { FactoryGirl.create(:product) }
it "should increase product count by one" do
expect{ subject }.to change{ Product.count }.by(1)
end
it "and then redirect to product's page" do
expect(subject).to redirect_to(product_path)
end
end
这是我的工厂:
FactoryGirl.define do
factory :product do
sequence(:title) { |n| "Book#{n}" }
description "Some crazy wibbles, they are fun"
image_url "freddie_mercury.jpg"
price 56.99
end
end
这是我的模特
class Product < ActiveRecord::Base
validates :title, :description, :image_url, presence: true
validates :price, numericality: {greater_than_or_equal_to: 0.01}
validates :title, uniqueness: true
validates :image_url, allow_blank: true, format: {
with: %r{\.(gif|jpg|png)\Z}i,
message: 'must be a URL for GIF, JPG or PNG image'
}
end
我的第一次测试通过(当我在工厂内更改名称时),但过了一段时间我得到了:
ProductsController creating new product should increase product count by one
Failure/Error: subject { FactoryGirl.create(:product) }
ActiveRecord::RecordInvalid:
Validation failed: Title has already been taken
这有点疯狂,因为我定义了序列(我尝试使用do ...结束块,除了'n'变量 - 我知道它有点傻,但不过)
然后,第二次测试也失败了:
ProductsController creating new product and then redirect to product's page
Failure/Error: expect(subject).to redirect_to(product_path)
ActionController::UrlGenerationError:
No route matches {:action=>"show", :controller=>"products"} missing required keys: [:id]
在那里,我只是不知道该尝试什么。我的一些尝试:
expect(subject).to redirect_to(product_path(assign(:product))
expect(subject).to redirect_to(product_path(assign(:product).id)
expect{ subject }.to redirect_to(product_path(assign(:product))
expect(subject).to redirect_to(product_path(subject))
expect(subject).to redirect_to(product_path(subject.id)
expect(subject).to redirect_to(product_path(response)
expect(response).to redirect_to(product_path(assign(:product))
我希望得到任何反馈,谢谢!
P.S。 这是rails_helper.rb
ENV['RAILS_ENV'] ||= 'test'
require 'spec_helper'
require File.expand_path('../../config/environment', __FILE__)
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!
end