【问题标题】:Mongoid + CucumberMongoid +黄瓜
【发布时间】:2012-04-05 20:28:40
【问题描述】:

我尝试通过 Capybara 在 Mongoid 支持的 Rails 3.2.3 应用程序中使用 Cucumber 运行场景。目的是让当前用户将一本书添加到他的收藏中。

一切正常,但最后一步定义,我检查书籍数量现在是否为一,失败了。

但如果我检查应用控制器,大小实际上增加了。实际上,当我在步骤定义中向用户发送reload 时,它通过了:

user.reload.books(true).size.should == 1

我担心这种行为一旦投入生产可能会损害我的应用程序。关于如何确保所有测试和应用行为一致的任何建议?

更新

我检查了 test.log 以了解发生了什么。 调用 reload 我得到这个查询到 MongoDB:

find({"count"=>"books",
"query"=>{:_id=>{"$in"=>[BSON::ObjectId('4f889b473dffd63235000004')]}},
"fields"=>nil}).limit(-1)

虽然没有重新加载,但我得到了这个:

find({"count"=>"books", "query"=>{:_id=>{"$in"=>[]}}, "fields"=>nil}).limit(-1)

如果我不重新加载模型,它实际上不会查询user,这对我来说没有多大意义。

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 mongodb cucumber mongoid


    【解决方案1】:

    以下对我有用(使用实际 Cucumber 示例更新)

    我构建了一个 Rails 项目来测试您的问题,rails 3.2.3、mongoid 2.4.8、mongo 1.6.2、mongodb 2.0.4、cucumber 1.1.9。

    以下(关联生成方法)按预期工作,无需刷新:

    user.books << book
    book.users << user
    

    然后我试图绕过关联,这就是我认为你正在做的事情。

    user.push(:book_ids, book.id)
    book.push(:user_ids, user.id)
    

    这些确实绕过了关联,导致不完整(单向而不是双向)引用,但内存和数据库状态是一致的。因此,我在之前的回答中对您遇到的问题的猜测是错误的,不需要刷新,您可能正在做其他事情。请注意,您/我们不想要不完整的引用,请不要直接推送到 Mongoid 引用关系的内部。

    您是否使用关联附加“

    这是模型:

    class User
      include Mongoid::Document
      field :first_name, type: String
      field :last_name, type: String
      has_and_belongs_to_many :books
    end
    
    class Book
      include Mongoid::Document
      field :title, type: String
      field :author, type: String
      has_and_belongs_to_many :users
    end
    

    黄瓜功能

    Feature: UserAndBook
      Test adding a book to a user_s books
    
      Scenario: add_book_to_user
        Given starting with no users and no books
        And a new user
        And that the new user has no books
        And a new book
        And add book to user
        Then I can check that the user has a book
    

    黄瓜步骤

    require 'test/unit/assertions'
    require File.expand_path('../../../test/test_helper', __FILE__)
    World(Test::Unit::Assertions)
    
    Given 'starting with no users and no books' do
      User.delete_all
      Book.delete_all
      assert_equal(0, User.count)
      assert_equal(0, Book.count)
    end
    
    Given 'a new user' do
      @user = User.create(first_name: 'Gary', last_name: 'Murakami')
    end
    
    Given 'that the new user has no books' do
      assert_equal(0, @user.books.count)
    end
    
    Given 'a new book' do
      @book = Book.create(title: 'A Tale of Two Cities', author: 'Charles Dickens')
    end
    
    Given 'add book to user' do
      @user.books << @book
    end
    
    Then 'I can check that the user has a book' do
      assert_equal(1, @user.books.count)
    end
    

    我愿意进一步交换信息以帮助解决您的问题。

    祝福,

    -加里

    附:查看日志,有趣的是 user.books.length 执行的是实际的 db "find count $in" 查询,而不是本地数组长度。

    上一个答案

    您几乎已经回答了自己的问题。在 Rails 中,每当模型的数据在数据库中发生更改时,您都需要使用 reload 方法,否则您将只查看模型先前加载/实例化/缓存的状态。仅更新一个属性,看起来很一致,但关联更复杂,不一致变得更加明显。

    【讨论】:

    • 我已经用 Cucumber 和 ActiveRecord/MySQL 制作了几个应用程序,我从来没有遇到过这种不一致,需要我强制重新加载我的模型。 Mongoid/MongoDB 有一些东西让我无法理解。
    • 你是如何指定用户和书籍之间的关系的?这些书是嵌入的还是单独的集合?您是如何将这本书添加到用户收藏中的?
    • 已编辑答案,其中包含我认为按您想要的方式工作的 Rails/Mongoid 项目的结果。
    • 我从测试中添加了一些日志记录,以尝试了解那里发生了什么。
    • 我已经用对我有用的实际 Cucumber 功能和步骤更新了我的答案,希望它对你有用并且你可以取得进步。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多