如何在Rails中测试更新方法

时间:2011-06-12 13:23:38

标签: ruby-on-rails functional-testing

我正在努力测试Rails中的更新方法。我使用标准的内置测试框架(test::unit)和Rails 3.0.8。我已经创建了一个最小的应用程序来测试它,但我无法让它工作。这是我的工作:

我创建了一个新的空白轨道应用程序:

rails new testapp

创建一个名为Collection的模型:

rails generate model collection name:string

运行rake db:migrate:

rake db:migrate

使用更新方法创建一个名为Collections的控制器:

rails generate controller collections update

在collection_controller.rb中,我添加了这个最小更新方法:

def update
  @collection = Collection.find(params[:id])
  @collection.update_attributes(params[:collection])
end

测试装置是默认值(collections.yml):

one:
  name: MyString

two:
  name: MyString

然后我将它添加到功能:

下的collection_controller_test.rb中
test "should update collection" do
  put :update, :id => collections(:one), :collection => {:name => 'MyString2'}
  assert_equal "MyString2", collections(:one).name
end

当我运行测试时:

rake test:functionals

此消息失败:

test_should_update_collection(CollectionsControllerTest) [/Users/atle/Documents/Rails/testapp/test/functional/collections_controller_test.rb:6]:
<"MyString2"> expected but was
<"MyString">.

以下是test.log的输出:

[1m[36mSQL (0.2ms)[0m  [1m SELECT name
FROM sqlite_master
WHERE type = 'table' AND NOT name = 'sqlite_sequence'
[0m
[1m[35mCollection Load (0.1ms)[0m  SELECT "collections".* FROM "collections" WHERE "collections"."id" = 980190962 LIMIT 1
Processing by CollectionsController#update as HTML
Parameters: {"id"=>#<Collection id: 980190962, name: "MyString", created_at: "2011-06-12 13:14:13", updated_at: "2011-06-12 13:14:13">, "collection"=>{"name"=>"MyString2"}}
[1m[36mCollection Load (0.2ms)[0m  [1mSELECT "collections".* FROM "collections" WHERE "collections"."id" = 980190962 LIMIT 1[0m
[1m[35mAREL (0.2ms)[0m  UPDATE "collections" SET "name" = 'MyString2', "updated_at" = '2011-06-12 13:14:13.394135' WHERE "collections"."id" = 980190962
Rendered collections/update.html.erb within layouts/application (1.5ms)
Completed 200 OK in 9ms (Views: 4.5ms | ActiveRecord: 1.2ms)

在日志中,我可以看到UPDATE语句,但我从未看到新的SELECT语句。

有人可以向我解释我的错误吗?

3 个答案:

答案 0 :(得分:17)

您可以对在HTTP响应期间创建的实例变量进行断言:

test "should update collection" do
  put :update, :id => collections(:one), :collection => {:name => 'MyString2'}
  assert_equal "MyString2", assigns(:collection).name
end

答案 1 :(得分:15)

您正在重新加载灯具数据而不是从数据库中读取数据。尝试像

这样的东西
assert_equal "MyString2", Collection.find(collections(:one)).name

您可能需要在灯具中指定ID。

免责声明:我没有对此进行测试。

答案 2 :(得分:3)

我最喜欢的变种:

test "should update collection" do
  coll = collections(:one)
  put :update, :id => coll, :collection => {:name => "MyString2"}
  assert_equal "MyString2", coll.reload.name
end

assigns(:collection)技巧实际上并不能保证记录已保存。这可能不是问题,也可能是一个惊喜。