使用RSpec测试嵌套资源会导致一个奇怪的失败



我写这篇文章是为了测试我的控制器的创建操作,该操作使用嵌套资源。我有一个具有has_many :users关联的Account模型。注册后,将创建一个具有单个用户的帐户。

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和get之间的区别:它需要一个符号,而得到一个字符串。

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散列通常包含字符串而不是符号的键。虽然我们确实使用符号访问它们,但这是因为它是一个无所谓访问的哈希,它不在乎是使用字符串还是符号访问。

为了使测试通过,您可以在设置期望值时对account_attributes哈希使用stringify_keys方法。然后,当Rspec比较哈希时,两者都将使用字符串键控。


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

Rails控制器通常很难测试,因为有许多等效的方法可以操作ActiveRecord模型。。。我通常会尽量让我的控制器变得愚蠢,我不会对它们进行单元测试,让它们的行为由更高级别的集成测试来覆盖。

相关内容

最新更新