失败(之前通过)RSpec 测试,即使在提交回来之后也是如此
Failing (previously passing) RSpec test even after commiting back
我正在追书APIs on Rails。我在第 8 章。在使用 RSpec 3.6 进行测试时,我遇到了以前没有遇到的错误。即使我 git checkout
提交了这些测试通过的提交,我也会得到它们。我确信他们是,因为我正在写博客 post,关于在 Rails 5.1.3 中关注这本书。我发现它们没有通过,在第 8 章末尾 运行 整个测试套件(失败的规范来自第 7 章和第 6 章)。在我 运行 规格主要针对特定文件之前。
所以我认为这个问题可能与系统有关,但我在应用程序之外的终端中唯一做的事情是:
$ swapoff -a
$ swapon -a
也许sudo apt-get update
所以我现在陷入了困境。
错误:
出现此错误的情况是 FactoryGirl
正在创建 4 个产品实例,而测试在对 #index
操作
的 GET 请求后获得 6 个实例
products_controller_spec.rb:
require 'rails_helper'
RSpec.describe Api::V1::ProductsController, type: :controller do
...
describe "GET #index" do
before(:each) do
4.times { FactoryGirl.create :product }
end
context "when is not receiving any product_ids parameter" do
before(:each) do
get :index
end
it "returns 4 records from the database" do
products_response = json_response[:products]
expect(products_response).to have(4).items
end
...
end
...
end
...
end
错误信息:
Api::V1::ProductsController GET #index when is not receiving any product_ids parameter returns 4 records from the database
Failure/Error: expect(products_response).to have(4).items
expected 4 items, got 6
如果我 puts products_response
在测试失败之前我得到 json 和这六个记录:
[
{
"id": 1,
"title": "Audible Remote Amplifier",
"price": "100.0",
"published": false,
"user": {
"id": 1,
"email": "blair.runolfsson@hirthe.info",
"created_at": "2017-08-27T12:13:26.977Z",
"updated_at": "2017-08-27T12:13:26.977Z",
"auth_token": "KA1ugPyXzXsULh6rN6QX",
"product_ids": [
1
]
}
},
{
"id": 2,
# rest of attributes
},
{
"id": 3,
# rest of attributes
},
{
"id": 4,
# rest of attributes
}
},
{
"id": 5,
# rest of attributes
},
{
"id": 6,
# rest of attributes
}
]
手动测试:
我的应用似乎运行良好。在点击 api.mydomain.dev/products
时,我在 rails console
中创建了 3 个产品后得到了很好的 json 响应:
{
"products": [
{
"id": 1,
"title": "product",
"price": "3.3",
"published": false,
"user": {
"id": 1,
"email": "example@marketplace.com",
"created_at": "2017-08-13T07:31:29.339Z",
"updated_at": "2017-08-27T13:09:06.948Z",
"auth_token": "HJLb-d4DpgxQDzkR1RDf",
"product_ids": [
1,
2
]
}
},
{
"id": 2,
# attrs of second product in json
},
{
"id": 3,
# attrs of third product in json
}
]
}
以及 URL 中的参数,例如 api.mydomain.dev/products?min_price=15&max_price=30
(顺便说一句,这是此处未包含的其余两个失败规范):
{
"products": [
{
"id": 3,
"title": "ps two",
"price": "20.0",
"published": false,
"user": {
"id": 2,
"email": "foo@bar.com",
"created_at": "2017-08-27T12:50:58.905Z",
"updated_at": "2017-08-27T12:50:58.905Z",
"auth_token": "YynJJeyftTEX49KU1-qL",
"product_ids": [
3
]
}
}
]
}
我在 spec/models/product_spec.rb 中还有 4 个错误,但为了让这个问题简短,我不会在此处包括它们。我觉得道理是一样的,这个错误最简洁。
我可能会提供更多代码,但是它在我的 github 存储库中 public,例如
app/models/product.rb or app/api/v1/products_controller.rb
总结:
该应用运行良好,并在手动测试时提供预期的输出。我在自动测试时遇到了错误,即使在提交回这些测试通过的地方之后也是如此。这可能表明问题出在系统方面。如果不是在系统端,为什么它在之前获得四个对象的同时获得了额外的两个对象?问题出在哪里?
可能是您的测试数据库没有被清理。尝试 运行 rails c test
并查询 Product.count
以查看测试数据库是否具有可能导致此错误的产品记录。您还可以在使用工厂创建记录之前将 byebug
或 puts Product.count
放在 before(:each) 块中,以确保在 运行 测试之前没有现有记录。如果是这种情况,您需要在测试前后手动或通过 DatabaseCleaner Gem.
清理数据库
提示:
最好为您正在创建和期望的记录数使用一个变量。
示例:
products_count = 4.times { FactoryGirl.create :product }
expect(products_response).to have(products_count).items
我正在追书APIs on Rails。我在第 8 章。在使用 RSpec 3.6 进行测试时,我遇到了以前没有遇到的错误。即使我 git checkout
提交了这些测试通过的提交,我也会得到它们。我确信他们是,因为我正在写博客 post,关于在 Rails 5.1.3 中关注这本书。我发现它们没有通过,在第 8 章末尾 运行 整个测试套件(失败的规范来自第 7 章和第 6 章)。在我 运行 规格主要针对特定文件之前。
所以我认为这个问题可能与系统有关,但我在应用程序之外的终端中唯一做的事情是:
$ swapoff -a
$ swapon -a
也许sudo apt-get update
所以我现在陷入了困境。
错误:
出现此错误的情况是 FactoryGirl
正在创建 4 个产品实例,而测试在对 #index
操作
products_controller_spec.rb:
require 'rails_helper'
RSpec.describe Api::V1::ProductsController, type: :controller do
...
describe "GET #index" do
before(:each) do
4.times { FactoryGirl.create :product }
end
context "when is not receiving any product_ids parameter" do
before(:each) do
get :index
end
it "returns 4 records from the database" do
products_response = json_response[:products]
expect(products_response).to have(4).items
end
...
end
...
end
...
end
错误信息:
Api::V1::ProductsController GET #index when is not receiving any product_ids parameter returns 4 records from the database
Failure/Error: expect(products_response).to have(4).items
expected 4 items, got 6
如果我 puts products_response
在测试失败之前我得到 json 和这六个记录:
[
{
"id": 1,
"title": "Audible Remote Amplifier",
"price": "100.0",
"published": false,
"user": {
"id": 1,
"email": "blair.runolfsson@hirthe.info",
"created_at": "2017-08-27T12:13:26.977Z",
"updated_at": "2017-08-27T12:13:26.977Z",
"auth_token": "KA1ugPyXzXsULh6rN6QX",
"product_ids": [
1
]
}
},
{
"id": 2,
# rest of attributes
},
{
"id": 3,
# rest of attributes
},
{
"id": 4,
# rest of attributes
}
},
{
"id": 5,
# rest of attributes
},
{
"id": 6,
# rest of attributes
}
]
手动测试:
我的应用似乎运行良好。在点击 api.mydomain.dev/products
时,我在 rails console
中创建了 3 个产品后得到了很好的 json 响应:
{
"products": [
{
"id": 1,
"title": "product",
"price": "3.3",
"published": false,
"user": {
"id": 1,
"email": "example@marketplace.com",
"created_at": "2017-08-13T07:31:29.339Z",
"updated_at": "2017-08-27T13:09:06.948Z",
"auth_token": "HJLb-d4DpgxQDzkR1RDf",
"product_ids": [
1,
2
]
}
},
{
"id": 2,
# attrs of second product in json
},
{
"id": 3,
# attrs of third product in json
}
]
}
以及 URL 中的参数,例如 api.mydomain.dev/products?min_price=15&max_price=30
(顺便说一句,这是此处未包含的其余两个失败规范):
{
"products": [
{
"id": 3,
"title": "ps two",
"price": "20.0",
"published": false,
"user": {
"id": 2,
"email": "foo@bar.com",
"created_at": "2017-08-27T12:50:58.905Z",
"updated_at": "2017-08-27T12:50:58.905Z",
"auth_token": "YynJJeyftTEX49KU1-qL",
"product_ids": [
3
]
}
}
]
}
我在 spec/models/product_spec.rb 中还有 4 个错误,但为了让这个问题简短,我不会在此处包括它们。我觉得道理是一样的,这个错误最简洁。
我可能会提供更多代码,但是它在我的 github 存储库中 public,例如 app/models/product.rb or app/api/v1/products_controller.rb
总结:
该应用运行良好,并在手动测试时提供预期的输出。我在自动测试时遇到了错误,即使在提交回这些测试通过的地方之后也是如此。这可能表明问题出在系统方面。如果不是在系统端,为什么它在之前获得四个对象的同时获得了额外的两个对象?问题出在哪里?
可能是您的测试数据库没有被清理。尝试 运行 rails c test
并查询 Product.count
以查看测试数据库是否具有可能导致此错误的产品记录。您还可以在使用工厂创建记录之前将 byebug
或 puts Product.count
放在 before(:each) 块中,以确保在 运行 测试之前没有现有记录。如果是这种情况,您需要在测试前后手动或通过 DatabaseCleaner Gem.
提示: 最好为您正在创建和期望的记录数使用一个变量。 示例:
products_count = 4.times { FactoryGirl.create :product }
expect(products_response).to have(products_count).items