2011-06-12 3 views
19

레일에서 업데이트 방법을 테스트하는 데 어려움을 겪고 있습니다. 테스트 프레임 워크 (test::unit) 및 레일즈 3.0.8에 내장 된 표준을 사용하고 있습니다. 지금이 테스트를위한 최소 응용 프로그램을 만들었지 만 제대로 작동하지 않습니다.레일에서 업데이트 방법을 테스트하는 방법

rails generate model collection name:string 

실행 레이크 dB :

rails new testapp 

가 모델이라고 컬렉션 만들기 :

나는 비어있는 새 레일 응용 프로그램을 만드는 : 여기에 내가 무엇을 마이그레이션 :

rake db:migrate 

업데이트 방법으로 Collections라는 컨트롤러를 만듭니다.

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

테스트 설비가 기본값 (collections.yml을)은 다음과 같습니다 :

one: 
    name: MyString 

two: 
    name: MyString 

그런 다음 나는 collection_controller_test이 추가 collection_controller.rb에서
rails generate controller collections update 

나는이 최소 업데이트 방법을 추가 할 수 있습니다. rb under functional :

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

테스트를 실행할 때 : 여기

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

이 test.log에서 출력됩니다 :

rake test:functionals 

은이 메시지와 함께 실패 나는 UPDATE 문을 볼 수있는 로그에서

[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) 

,하지만 난 볼 수 없습니다 새로운 SELECT 성명

내가 잘못하고있는 것을 누군가 나에게 설명해 줄 수 있습니까?

+2

분명히 묻는 질문은 +1입니다.새로운 사용자가이 수준의 세부적인 질문을하는 것이 좋을 것 같습니다. 당신의 문제는 확실히 db 대신에 fixture로부터 간단히 읽는, 당신의 주장에있는'collections (: one) '에서 유래합니다. Cameron과 Teddy는 모두 아래에서이 점을 올바르게 설명합니다. (BTW :'factory_girl'을 들여다 보면 조명을 완전히 덤프 할 수 있습니다. 시작하기에 편리하지만 나중에는 끔찍한 혼란이 있습니다.) – jdl

+0

조명기와 db는 두 개의 별개의 위치입니다. 비품이 시작시에 db로 읽혀지고 그 콜렉션 (: 하나)이 db에서 읽힌 것으로 가정합니다. 물건을 지워 줘서 고마워, 그 factory_girl을 살펴 보겠습니다 :) – Atle

답변

13

데이터베이스에서 읽는 대신 조명기 데이터를 다시로드하는 중입니다. 같은 것을 시도하십시오

assert_equal "MyString2", Collection.find(collections(:one)).name 

조명기에서 ID를 지정해야 할 수도 있습니다.

면책 조항 : 테스트하지 않았습니다.

+1

이것은 효과가 있습니다. 이제 테스트가 작동합니다. 감사합니다! – Atle

+0

필요하지 않은 경우 테스트에서 DB를 사용하지 마십시오. DB가 작동하는지 테스트하고 싶지는 않습니까? – schmijos

17

당신은 HTTP 응답 과정에서 생성되는 인스턴스 변수에 주장 할 수 있습니다 :이의

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

당신의 제안도 효과가 있었지만 나는 그가 처음 이었기 때문에 Camerons 대답을 받아 들였습니다;) 감사합니다! – Atle

+0

이것은 데이터베이스를 사용하지 않기 때문에 더 나은 대답입니다. – schmijos

+0

정답입니다. Collection.find (collections (: one))는 추악합니다. – hellion

2

내가 가장 좋아하는 변종 :

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

assigns(:collection) 트릭이 실제로 기록을 보장하지 않습니다 구원 받았다. 이것은 문제가되지 않을 수도 있고 놀랄 수도 있습니다.

+0

가능한 경우'assigns '를 사용하십시오. 테스트하려는 대상에 대해 데이터베이스 상호 작용이 필요하지 않습니다. – schmijos