2016-04-08 8 views
0

私は失敗し続けているrspecテストを持っています。問題を引き起こしている可能性があるのは、created_atという形式のテストがmysqlタイムスタンプであり、アプリケーション自体で正しく翻訳されていないということだけです。mysqlのタイムスタンプ形式のため、私のrspecテストに失敗しましたか?

describe '#send_peer_shortage_notifications' do 
    subject { described_class.send_peer_shortage_notifications } 

     context 'minimum number of peer assessments not in pending/complete and limbo email interval day' do 
      limbo_interval_array = Array.new(10) { |i| i*Reminders::LIMBO_EMAIL_INTERVAL_DAYS } 

      let!(:evaluation) { create(:evaluation, created_at: (Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME + limbo_interval_array.sample.days).ago) } 
      let!(:assessments) do 
      create_list(:assessment, 
      Evaluation::MINIMUM_NUM_PEERS, 
      evaluation: evaluation, 
      state: [:expired, :declined].sample) 
      end 

      it 'sends limbo email' do 
      puts evaluation.created_at 
      expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1) 
      end 
     end 

出力:ここで私はReminders::LIMBO_EMAIL_INTERVAL_DAYSの変数を含む配列からサンプリングしてる私のreminders_spec.rbテストは、(3に設定)created_at日付電子メールが送信されるべきものであるという条件を確立することですputs evaluation.created_atはmysqlのタイムスタンプ形式(つまり2016-04-01 19:44:43 UTC)で、.to_dateのような書式設定には応答せず、テストが失敗する可能性があります。ここでは、障害メッセージは次のとおりです。

def self.send_peer_shortage_notifications 
    time = Time.current - Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME 
    range = time..Time.current 
    today = Time.current.to_date 

    evaluations = Evaluation.arel_table 
    assessments = Assessment.arel_table 

    left_join = evaluations 
       .join(assessments, Arel::Nodes::OuterJoin) 
       .on(evaluations[:id].eq(assessments[:evaluation_id]), 
        assessments[:state].in([:pending, :complete]), 
        assessments[:assessor_id].not_in([evaluations[:user_id], 
                 evaluations[:manager_id]])) 
       .join_sources 

    relation = Evaluation 
       .in_process 
       .joins(left_join) 
       .where(created_at: range) 
       .group(:user_id) 
       .having(evaluations[:user_id].count.lt(Evaluation::MINIMUM_NUM_PEERS)) 

    relation.find_each do |evaluation| 
     days_in_limbo = (today - (evaluation.created_at + Evaluation::ASSESSMENTS_COMPLETION_WAIT_TIME).to_date).to_i 
     if days_in_limbo > 0 && days_in_limbo % Reminders::LIMBO_EMAIL_INTERVAL_DAYS == 0 
     EvaluationMailer.delay.limbo_notification(evaluation) 
     end 
    end 
    end 

Failures: 

    1) Reminders#send_peer_shortage_notifications minimum number of peer assessments not in pending/complete and limbo email interval day sends limbo email 
    Failure/Error: expect { subject }.to change { ActionMailer::Base.deliveries.count }.by(1) 
     expected result to have changed by 1, but was changed by 0 
    # ./spec/lib/reminders_spec.rb:110:in `block (4 levels) in <top (required)>' 

ここで私はdays_in_limboを把握し、電子メールを送信するための条件を設定するために.to_dateto_iを使用reminders.rb内のロジックです:私はちょうどこのテストがフォーマットやその他の理由でどうして渡されないのか、rspecでフォーマットを変換してRailsでフォーマットできる情報を渡す方法があるかどうかを知りたいだけです。私は自分のcronジョブを変更するか、whenevertimecopのような宝石を使うなど、ロジックに代わるソリューションを探しているわけではありませんが、とにかくお勧めしたいと思ったら感謝します:)

+0

あなたのrspecエラーは何ですか? – Ilya

+0

申し訳ありませんが...それが含まれている必要があります! '失敗: 1)リマインダー#send_peer_shortage_notifications保留中/完全リムーバメールインターバルの日にリムーバメールを送信していないピアアセスメントの最小数 失敗/エラー:{件名} .toの変更{ActionMailer :: Base.deliveries.count} .by(1) 期待される結果が1だけ変更されたが、0によって変更された。 #./spec/lib/reminders_spec.rb:110:inブロック(4レベル) '' – jnapolitan

+0

質問を編集する) – Ilya

答えて

0

コメント/回答ありがとうございました。問題は、私がテストしていたcreated_atの日付の評価を含まないrange変数でした。

0

100%しかし、あなたが期待しているように、データベースの状態がexpect...changeブロック内で変化しているとは思わない。この場合もsubjectを使用するのは適切ではないと私は考えています。

subjectをあなたのの内容で置き換えたとすれば、あなたは合格テストを受けるかもしれません。例の前にlet!が実行されるので、let!の代わりにletを使用することもできます。