Rspec 规格有时通过,有时不通过';T

Rspec 规格有时通过,有时不通过';T,rspec,request,bdd,database-cleaner,Rspec,Request,Bdd,Database Cleaner,我有要求规格: 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.s

我有要求规格:

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)>'
编辑:

控制器:

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.(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

@json.length
几乎总是
0
,但有时是
1

首先,使用
#让
覆盖实例变量。然后将工厂创建放在(:each)
块之前的
中。还可以使用
#create_list
创建工厂列表。最后也是最重要的一点,向我们展示您的控制器,可能还有您的型号代码。@halleth
响应的输出是什么。body
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