我有要求规格:
describe "Matches" do
describe "GET /matches" do
it "works! (now write some real specs)" do
# Run the generator again with the --webrat flag if you want to use webrat methods/matchers
get matches_path
response.status.should be(200)
end
it 'return JSON array' do
get matches_path(format: :json)
@json = JSON.parse(response.body)
@json.should be_an Array
end
context 'and there are some entries' do
it 'return all matches' do
@matches = (1..4).map { FactoryGirl.create(:match) }
get matches_path(format: :json)
@json = JSON.parse(response.body)
@json.length.should == @matches.size
end
end
end
end
有时完全通过,但有时我得到:
1) Matches GET /matches and there are some entries return all matches
Failure/Error: @json.length.should == @matches.size
expected: 4
got: 5 (using ==)
# ./spec/requests/matches_spec.rb:29:in `block (4 levels) in <top (required)>'
我不知道为什么,这很烦人。我在每次测试后使用以下命令清理数据库database_cleaner
:
Spork.prefork do
# ...
require 'database_cleaner'
RSpec.configure do |config|
# ...
config.infer_base_class_for_anonymous_controllers = true
config.before(:suite) do
DatabaseCleaner.strategy = :transaction
DatabaseCleaner.clean_with(:truncation)
end
end
end
Spork.each_run do
RSpec.configure do |config|
config.before(:each) do
DatabaseCleaner.start
end
config.after(:each) do
DatabaseCleaner.clean
end
# ...
end
end
编辑:
控制器:
class MatchesController < ApplicationController
# GET /matches
# GET /matches.json
def index
@matches = Match.all
end
# GET /matches/1
# GET /matches/1.json
def show
@match = Match.find(params[:id])
end
end
看法:
json.array!(@matches) do |match|
json.partial! match
end
部分的:
json.(match, :id, :ladder, :start)
json.player_one match.player_one.to_builder
json.player_two match.player_two.to_builder
json.player_one_odds match.player_one_odds.value
json.player_two_odds match.player_two_odds.value
模型:
class Match < ActiveRecord::Base
belongs_to :tournament
belongs_to :league
has_many :odds, dependent: :destroy
belongs_to :winner, class_name: 'Competitor'
belongs_to :player_one, class_name: 'Competitor'
belongs_to :player_two, class_name: 'Competitor'
validates :start, presence: true
validates :tournament, presence: true, :if => -> { league.nil? }
validates :league, presence: true, :if => -> { tournament.nil? }
validates :player_one_id, presence: true
validates :player_two_id, presence: true
validates :player_one_odds, presence: true
validates :player_two_odds, presence: true
validate :in_future
before_save :save_odds
attr_accessible :start, :league_id, :tournament_id, :ladder, :player_one_id, :player_two_id,
:winner_id, :player_one_odds, :player_two_odds
attr_readonly :player_one_id, :player_two_id
def player_one_odds
@player_one_odds ||= odds.where(:competitor_id => player_one).order('updated_at DESC').first
end
def player_two_odds
@player_two_odds ||= odds.where(:competitor_id => player_two).order('updated_at DESC').first
end
def player_one_odds=(value)
@player_one_odds = Odd.new(competitor: player_one,
match: self,
close_at: start,
value: value)
end
def player_two_odds=(value)
@player_two_odds = Odd.new(competitor: player_two,
match: self,
close_at: start,
value: value)
end
private
def in_future
errors.add(:start, I18n.t('match.in_future')) if start.nil? || start < Time.now
end
def save_odds
player_one_odds.save && player_two_odds.save
end
end
现在我也有类似的测试:
context 'and there are some entries' do
let(:matches) { FactoryGirl.create_list(:match, 4) }
it 'return all matches' do
get api_matches_path(format: :json)
puts response.body
@json = JSON.parse(response.body)
@json.length.should == 4
end
end
而且@json.length
几乎总是0
如此,但有时确实如此1
。