0

我有一个应用程序使用未读 gem将某些模型标记为用户已读或未读。这颗宝石非常甜美,可以在应用程序中完美运行。不幸的是,在进行一些涉及模型的 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_userFactoryGirl 正确创建并具有 id。reviewsFactoryGirl 生成的数组是create_list合法的并且已user_id正确填写。从上面的代码中可以看出,我已经尝试将类中unreadgem的方法存根,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(即使评论有关联的用户)。我对这里发生的事情完全不知所措,真的需要有人的天才来让我指出正确的方向。感谢任何人都可以提供的任何帮助。为了完整起见,以下是有关我的环境的一些事实:

  • 操作系统:Mac 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方法的共享宏的建议。它没有修复错误。

4

1 回答 1

0

我没有详细检查您的代码,但在我看来,您正在使用带有无效参数的范围“unread_by”。它必须是持久用户(具有 ID)。

我刚刚在 gem 中添加了改进的参数检查并更新了 0.1.2,因此请使用最新版本测试您的代码。

于 2013-01-27T08:53:23.457 回答