失败(先前通过)RSpec测试即使在提交后

问题描述:

我正在关注该书APIs on Rails。我在第8章。当使用RSpec 3.6进行测试时,我收到了以前没有得到的错误。即使我在git checkout这些测试通过的提交中,我也会收到它们。我确定他们是,因为我正在撰写一篇博文,关于在Rails 5.1.3中关注这本书。我发现他们没有通过,在第8章结束时运行整个测试套件(失败的规范来自第7章和第6章)。在我运行大多数特定文件的规格之前。失败(先前通过)RSpec测试即使在提交后

所以我认为这个问题可能是系统相关的,但是我是在终端的应用程序之外做的唯一的事情就是:

$ swapoff -a 
$ swapon -a 

,也许sudo apt-get update

所以我左右为难现在。

该错误:

与此错误的情况是FactoryGirl是创建产品的4个实例,而测试GET请求后得到6〜#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": "[email protected]", 
     "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,我得到了很好的JSON响应中rails console创造3个产品后:

{ 
    "products": [ 
    { 
     "id": 1, 
     "title": "product", 
     "price": "3.3", 
     "published": false, 
     "user": { 
     "id": 1, 
     "email": "[email protected]", 
     "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 
    } 
    ] 
} 

,并在网址参数一样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": "[email protected]", 
     "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仓库中是公开的,例如, app/models/product.rbapp/api/v1/products_controller.rb

总结:

该应用程序工作正常并且提供期望的输出,同时人工测试。即使在提交到这些测试通过的地方之后,我也会在自动测试时发现错误。这可能表明问题出在系统方面。如果它不在系统方面,为什么它在获得四个之前获得额外的两个对象?哪里有问题?

可能是因为您的测试数据库没有被清理。尝试运行rails c test并查询Product.count以查看测试数据库是否包含可能导致此错误的产品记录。在使用工厂创建记录以确保在运行测试之前不存在任何记录之前,您还可以在之前(:每个)块中放入byebugputs Product.count。如果是这样的话,您需要手动或通过DatabaseCleaner Gem在测试之前和之后清理数据库。

提示: 对于您创建和期望的记录数使用变量也更好。 例如:

products_count = 4.times { FactoryGirl.create :product } 
expect(products_response).to have(products_count).items 
+0

是的,就是这样。为了快速检查,我按照你所说的去了'rails c test',并且这2条记录在那里(不知道怎么做)。我用'Product.destroy_all'销毁了它们,并且所有五个测试都通过了。似乎我需要挖掘DatabaseCleaner文档。谢谢师父。 – ToTenMilan

+0

很高兴我能帮到你。干杯。 –