这是我在这里的第一个问题,我实际上是在问,因为我很绝望而且我的课程导师已经离开...我正在关注网络开发课程,并在使用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
我甚至尝试将'评论'声明为:
context "register comment" do
before do
@comments = @product.comments
end
end
但这没有任何区别。任何有关此事的帮助都会非常感激,因为我疯了,过去3天在电脑附近砸东西!接下来就是粉碎电脑本身! 非常感谢阅读。希望你过得愉快。
答案 0 :(得分:0)
如果不了解您的域名,模型关联等,很难真正清楚。但是,这里的主要问题似乎是使用上下文块。
在每个上下文块context "create comment 1" do
中设置上下文,使用before块设置测试,然后关闭上下文块。这些块中的每一个都是彼此不同的,因为它们当前编写的目的没有任何意义 - 因为没有任何期望在其中任何一个中进行测试。
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
代码可能不正确,但应更清楚地显示您希望如何构建测试。你可能需要进一步调整它。
以下代码采用类似于餐馆和评论的示例,可以比作产品和评论/评级:
##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
值得注意的是,这些测试可能会被let
或before
严重重构,甚至使用FactoryGirl
之类的工具来创建测试对象,但是应该提供解决问题的有用示例。
希望这会有所帮助。