ruby-on-rails - 使用 RSpec 测试嵌套资源会导致奇怪的失败

标签 ruby-on-rails ruby testing rspec

我写这个是为了测试我的 Controller 使用嵌套资源的创建操作。我有一个带有 has_many :users 关联的帐户模型。注册后,将创建一个只有一个用户的帐户。

  describe "POST #create", focus: true do
    let(:account) { mock_model(Account).as_null_object }

    before do
      Account.stub(:new).and_return(account)
    end

    it "creates a new account object" do
      account_attributes         = FactoryGirl.attributes_for(:account)
      user_attributes            = FactoryGirl.attributes_for(:user)
      account_attributes[:users] = user_attributes

      Account.should_receive(:new).with(account_attributes).and_return(account)
      post :create, account: account_attributes
    end
  end

这是我得到的失败输出;注意 expected 和 got 之间的区别:它期望一个符号,而它得到一个字符串。

1) AccountsController POST #create creates a new account object
     Failure/Error: Account.should_receive(:new).with(account_attributes).and_return(account)
       <Account(id: integer, title: string, subdomain: string, created_at: datetime, updated_at: datetime) (class)> received :new with unexpected arguments
         # notice that expected has symbols while the other users strings...
         expected: ({:title=>"ACME Corp", :subdomain=>"acme1", :users=>{ ... }})
              got: ({"title"=>"ACME Corp", "subdomain"=>"acme1", "users"=>{ ... }})
     # ./spec/controllers/accounts_controller_spec.rb:34:in `block (3 levels) in <top (required)>'

我不禁注意到这段代码也有点味道。我不知道我是否正在做这件事。我是 RSpec 的新手,所以如果你能对我的努力提供一些反馈,我会加分。

最佳答案

params 散列通常包含字符串而不是符号的键。虽然我们确实使用符号访问它们,但这是因为它是一个 Hash with indifferent access。 ,它不关心它是使用字符串还是符号访问。

为了让你的测试通过,你可以使用 stringify_keys设置期望时 account_attributes 散列上的方法。然后,当 Rspec 比较哈希时,两者都将以字符串为键。


现在,关于您提出的评论:实例化一个帐户真的是您对 Controller 的期望吗?如果您将断言/期望放在更具体、外部可见的行为上,而不是放在您的对象应该使用的每个方法上,您的测试将不那么脆弱。

Rails Controller 通常很难测试,因为有许多等效的方法来操作 ActiveRecord 模型......我通常会尽量让我的 Controller 尽可能笨,而且我不会对它们进行单元测试,将它们的行为留给被更高级别的集成测试覆盖。

关于ruby-on-rails - 使用 RSpec 测试嵌套资源会导致奇怪的失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12760755/

相关文章:

ruby-on-rails - 设计Omniauth,如何链接谷歌账户

javascript - 如何从一次提交更新两个_form?

spring - Mockito 的 when() 方法无法正常工作

testing - .ts 文件的最小大小

ruby-on-rails - rails : Custom text for rails form_for label

ruby-on-rails - 在生产中禁用 GraphQL 自省(introspection)请求

ruby-on-rails - rails 5 : prepopulate search form inputs using form_with with params without having to do it manually for each field

ruby-on-rails - 我怎么知道 Rails 已经加载/缓存了一个 Activerecord 类属性?

ruby - 如何匹配字符串直到文本文件结尾?

javascript - 如何摆脱 v-on 处理程序 : "TypeError: _vm.myFcn is not a function"? 中的错误