【问题标题】:what is wrong with this rspec failure code这个 rspec 失败代码有什么问题
【发布时间】:2015-12-01 12:03:45
【问题描述】:

这是我在这里的第一个问题,我实际上是在问,因为我很绝望,我的课程导师不在……我正在学习一个 Web 开发课程,并在使用 RSpec 进行单元测试时遇到了这个问题。 .我使用的命令行是rspec spec/models(该文件夹中的文件是:product_spec.rb)。这是我用来测试的代码:

    require 'rails_helper'

    describe Product do

        context "when the Product has comments" do

            before do
                @product = Product.create(:name => "product model")
            end
        end

        context "when user has email & password" do

            before do
                @user = User.create(:email => "testspec@test.com", :password => "passtheword")
            end
        end



    context "create comment 1" do

        before do
            @product.comments.create(:rating => 1, :user => @user, :body => "Awful comment!")
        end
    end

    context "create comment 2" do

        before do
            @product.comments.create(:rating => 3, :user => @user, :body => "another awful comment!")
        end
    end

    context "create coment 3" do

        before do
            @product.comments.create(:rating => 5, :user => @user, :body => "yet another awful comment!")
        end
    end

    context "rating average" do
        before { @average_rating = Product.comments.count(:rating) }
        it "returns the average rating" do
            expect(@average_rating).to eq 3
        end
    end

    end

这是我从 RSpec 得到的错误:

    F

    Failures:

      1) Product rating average returns the average rating
         Failure/Error: before { @average_rating = Product.comments.count(:rating) }

 NoMethodError:
   undefined method `comments' for #<Class:0x007fe22e58b6d8>
 # ./spec/models/product_spec.rb:43:in `block (3 levels) in <top (required)>'

Finished in 0.00099 seconds (files took 1.61 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/models/product_spec.rb:44 # Product rating average returns the average rating

我什至尝试过这样声明“cmets”:

context "register comment" do
  before do
    @comments = @product.comments
  end
end

但这并没有什么不同。任何关于此事的帮助将不胜感激,因为我快疯了,过去 3 天在电脑附近砸东西!接下来就是砸电脑了!! 非常感谢您的阅读。希望你今天过得愉快。

【问题讨论】:

  • 哦!!忘了补充,我应该测试提交的 cmets 的平均评分,但不要让事情复杂化,在这个阶段,如果代码返回已提交的 cmets/评分数,我会很高兴;因此 =3 仍然有效,因为等级 1 + 3 + 5 / 3 仍然给出 3。谢谢。

标签: rspec


【解决方案1】:

如果不了解您的领域、模型关联等,就很难真正清楚。但是,您的主要问题似乎是上下文块的使用。

在每个上下文块context "create comment 1" do 中设置一个上下文,使用一个前块来设置您的测试,然后关闭上下文块。这些块中的每一个都彼此不同,并且由于它们目前的编写没有任何目的 - 因为没有期望在其中任何一个中进行测试。

context "rating average" do
  ##This sets up your test within this context block.
  before do
    Product.comments.create(:rating => 1, :user => @user, :body => "Awful comment!")
    Product.comments.create(:rating => 3, :user => @user, :body => "another awful comment!")
    Product.comments.create(:rating => 5, :user => @user, :body => "yet another awful comment!")
  end

   ##Now lets test it.
   let(:average_rating) { Product.comments.count(:rating) }

   it "returns the average rating" do
     expect(average_rating).to eq 3
   end
end

代码可能不正确,但应该更清楚地显示您希望如何构建测试。您可能需要进一步调整。

以下代码采用类似的餐厅和评论示例,可以将其比作产品和 cmets/ratings:

##In this example we need to create some users to create our restaurants and then reviews so use RSpec's ```let``` which is lazily evaluated.
let(:user) { User.create(email: "test@test.com", password: "password" }
let(:user2) { User.create(email: "test2@test.com", password: "passwordpass2" }

##Then we test (and also set up the conditions within the test itself).
context '1 review' do
  it 'returns that rating' do
    restaurant = user.restaurants.create(name: 'BK Lounge')
    restaurant.build_review({"thoughts" => "Great!", "rating" => 4}, user).save
    expect(restaurant.average_rating).to eq 4
  end
end

context 'multiple reviews' do
  it 'returns the average' do
    restaurant = user.restaurants.create(name: 'BK Lounge')
    restaurant.build_review({"thoughts" => "Not great!", "rating" => 1}, user).save
    restaurant.build_review({"thoughts" => "Great!", "rating" => 5}, user2).save
    expect(restaurant.average_rating).to eq 3
  end
end

值得注意的是,这些测试可以通过letbefore 进行大量重构,甚至可以使用FactoryGirl 等工具来创建我们的测试对象,但应该提供一个有用的示例来解决您的问题。

希望这会有所帮助。

【讨论】:

  • 非常感谢您的时间和帮助;我真的非常感激。尽管它无法解决问题,但我仍然能够完全理解它是如何工作的……按照您的说明,我几乎立即就可以看出我在哪里遇到了这些反复出现的问题。
  • 它没有解决问题的唯一原因是我犯了一个非常愚蠢的错误,并且没有检查模型的验证!!!!有 4 个对象需要验证,而我只给了 1 个……doh !!!非常感谢您的时间,霍克先生;真的非常感谢!!希望你今天过得愉快:)
猜你喜欢
  • 1970-01-01
  • 2014-06-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-07
  • 2014-08-29
  • 2013-06-05
  • 2014-06-04
相关资源
最近更新 更多