未読の宝石を使用して、特定のモデルをユーザーに対して既読または未読としてマークするアプリがあります。この宝石は非常に甘く、アプリで問題なく動作します。残念ながら、モデルを含むいくつかの Rspec テストに取り組んでいるときに奇妙なエラーが発生しておりact_as_readable
、私の人生では、次にどこに行くべきかを理解することはできません。素晴らしい StackOverflow コミュニティが私を助けてくれることを願っています。必要な詳細は次のとおりです。
モデル法
def unread_subscriptions
reviews = Array.new
subscriptions = Subscription.where(user_id: self.id)
unless subscriptions.empty?
subscriptions.each do |subscription|
subscription_reviews = Review.where(user_id: subscription.subscription_user_id)
unless subscription_reviews.empty?
subscription_reviews.each do |subscription_review|
if subscription_review.unread?(self)
reviews << subscription_review
end
end
end
end
end
reviews.sort_by(&:created_at).reverse
end
このコードには、改善またはリファクタリングできる明らかな場所がいくつかあります。これが、まさに私がテストを書いている理由です。そのため、目前のエラーに焦点を当てて議論を続けましょう。
Rspec テスト ブロック
describe "#unread_subscriptions", focus: true do
context "when subscriptions and subscription reviews are not empty" do
let(:subscription_user) { FactoryGirl.create(:user) }
let(:reviews) { FactoryGirl.create_list(Review, 3, user: subscription_user) }
before(:each) {
subscription_double = double(Subscription)
subscription_double.stub(:where)
.with(user_id: user.id)
.and_return(
FactoryGirl.create(:subscription,
user_id: user.id,
subscription_user_id: subscription_user.id))
review_double = double(Review)
review_double.stub(:unread_by).with(user).and_return(reviews)
review_double.stub(:unread?).with(user).and_return(true)
review_double.stub(:where).with(user_id: subscription_user.id).and_return(reviews)
}
its(:unread_subscriptions) { should be_instance_of(Array) }
its(:unread_subscriptions) { should_not be_empty }
end
end
上記のコードはすべて正常に動作しているようです。はsubscription_user
FactoryGirl によって適切に作成され、ID を持っています。reviews
FactoryGirl によって生成された配列はcreate_list
正当でありuser_id
、適切に入力されています。上記のコードでわかるようにunread
、クラスの gemのメソッドをスタブ化しようとしましたReview
が、適切に機能していないようです。
レビューファクトリー
FactoryGirl.define do
sequence :created_at do |n|
n.minutes.ago
end
factory :review do
user
bar
body "MyText"
rating 3
created_at
end
end
これらのテストを実行するrspec spec/models/user_spec.rb -f d
と、次の出力が得られます。
Run options: include {:focus=>true}
User
#unread_subscriptions
when subscriptions and subscription reviews are not empty
unread_subscriptions
example at ./spec/models/user_spec.rb:231 (FAILED - 1)
unread_subscriptions
example at ./spec/models/user_spec.rb:232 (FAILED - 2)
Failures:
1) User#unread_subscriptions when subscriptions and subscription reviews are not empty unread_subscriptions
Failure/Error: its(:unread_subscriptions) { should be_instance_of(Array) }
ActiveRecord::StatementInvalid:
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND read_marks.timestamp >= reviews.created_at WHERE `reviews`.`id` = 1 AND ' at line 4: SELECT 1 FROM `reviews` LEFT JOIN read_marks ON read_marks.readable_type = 'Review'
AND read_marks.readable_id = reviews.id
AND read_marks.user_id =
AND read_marks.timestamp >= reviews.created_at WHERE `reviews`.`id` = 1 AND (read_marks.id IS NULL) ORDER BY created_at DESC LIMIT 1
# ./app/models/user.rb:217:in `block (2 levels) in unread_subscriptions'
# ./app/models/user.rb:216:in `block in unread_subscriptions'
# ./app/models/user.rb:212:in `unread_subscriptions'
# ./spec/models/user_spec.rb:231:in `block (4 levels) in <top (required)>'
2) User#unread_subscriptions when subscriptions and subscription reviews are not empty unread_subscriptions
Failure/Error: its(:unread_subscriptions) { should_not be_empty }
ActiveRecord::StatementInvalid:
Mysql2::Error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'AND read_marks.timestamp >= reviews.created_at WHERE `reviews`.`id` = 4 AND ' at line 4: SELECT 1 FROM `reviews` LEFT JOIN read_marks ON read_marks.readable_type = 'Review'
AND read_marks.readable_id = reviews.id
AND read_marks.user_id =
AND read_marks.timestamp >= reviews.created_at WHERE `reviews`.`id` = 4 AND (read_marks.id IS NULL) ORDER BY created_at DESC LIMIT 1
# ./app/models/user.rb:217:in `block (2 levels) in unread_subscriptions'
# ./app/models/user.rb:216:in `block in unread_subscriptions'
# ./app/models/user.rb:212:in `unread_subscriptions'
# ./spec/models/user_spec.rb:232:in `block (4 levels) in <top (required)>'
Finished in 8.88 seconds
2 examples, 2 failures
Failed examples:
rspec ./spec/models/user_spec.rb:231 # User#unread_subscriptions when subscriptions and subscription reviews are not empty unread_subscriptions
rspec ./spec/models/user_spec.rb:232 # User#unread_subscriptions when subscriptions and subscription reviews are not empty unread_subscriptions
何らかの理由で、readmarks
クエリがレビューのユーザー ID を取得していません (レビューにユーザーが関連付けられていても)。私はここで何が起こっているのか完全に途方に暮れており、正しい方向に向けるために誰かの天才が本当に必要です. 誰でも提供できるヘルプをありがとう。完全を期すために、ここに私の環境に関するいくつかの事実があります:
- OS:マックOSX 10.7.5
- Ruby バージョン: ruby 1.9.3p194 (2012-04-20 リビジョン 35410) [x86_64-darwin11.4.0]
- Rails バージョン: Rails 3.2.3
- RVM バージョン: rvm 1.15.8 (安定版)
- RSpec バージョン: 2.11.1
- 未読の宝石バージョン: 0.1.1
- factory_girl_rails バージョン: 4.1.0
エクストラ:メソッドの共有マクロに関するこのスレッドの提案も使用していwait
ます。エラーは修正されませんでした。