Hey Everyone,
I have a function test the is failing (despite the fact the function
actually works in the application). I was looking for some debug
advice on how to find my problem.
Here is the test:
def test_should_delete_word
assert_equal ‘published’, words(:one).status
debugger
delete :destroy, :id => words(:one).to_param
assert_equal 'deleted', words(:one).status
end
It fails on the last with: <“deleted”> expected but was <“published”>.
//My fixture:
one:
word: cup
was_created_by_user: true
status: published
user_id: 1
ip_address: ‘129.1.0.0’
@word.definitions.each do |h|
h.status = 'deleted'
h.save
end
respond_to do |format|
format.html { redirect_to(words_url) }
end
end
Now the actually application works just like expected changes all
appropriate columns in the db.
I think the problem is that after I run the delete method in the test
the fixtures are reloaded before the next assert so the status is put
back to “published” when it should be “deleted”. I think this is the
problem only because when I step through the process in the debugger I
see:
force_reload = fixtures.pop if fixtures.last == true ||
fixtures.last == :reload
Right after it calls the delete.
I think the problem is that after I run the delete method in the test
the fixtures are reloaded before the next assert so the status is put
back to “published” when it should be “deleted”. I think this is the
problem only because when I step through the process in the debugger I
see:
It’s the opposite problem: fixtures are not reloaded, so although the
copy in the database now has status deleted words(:one) is now a stale
object - you just need to reload it before making testing whether it’s
status has changed.
I think the problem is that after I run the delete method in the test
the fixtures are reloaded before the next assert so the status is put
back to “published” when it should be “deleted”. I think this is the
problem only because when I step through the process in the debugger I
see:
It’s the opposite problem: fixtures are not reloaded, so although the
copy in the database now has status deleted words(:one) is now a stale
object - you just need to reload it before making testing whether it’s
status has changed.
Fred
It’s crap like this that has put me off fixtures. Try something like
Machinist instead. Fixtures just don’t work for many common testing
scenarios.
On Sep 1, 10:49 pm, Marnen Laibow-Koser <rails-mailing-l…@andreas- s.net> wrote:
Frederick C. wrote:
It’s crap like this that has put me off fixtures. Try something like
Machinist instead. Fixtures just don’t work for many common testing
scenarios.
anything that uses actual activerecord objects can have this sort of
issue because you can have 2 entirely separate objects that represent
the same row in the database.
Here is the test:
def test_should_delete_word
assert_equal ‘published’, words(:one).status
debugger
delete :destroy, :id => words(:one).to_param
assert_equal 'deleted', words(:one).status
end
It fails on the last with: <“deleted”> expected but was <“published”>.
if i understand correctly
your problem here is you are checking values from fixture instead of
database
like this
assert_equal ‘deleted’, words(:one).status
instead you must check your status from database
assert_equal ‘deleted’, check value from database not from fixture
end
It claims “Couldn’t find Word with ID=id” same with assert_equal
‘deleted’, Word.find(:id).status
I also tried using Machinist but really don’t know what objects to
call on to try anything. Wouldn’t I have to first create a word then
find the word delete the ford and check the value. At that point it
sounds more like an integration test then Functional.
def test_should_delete_word
word = Word.plan
delete :destroy, :id => word.id // Returns cannot find id as the
object was never stored?
assert_equal ‘deleted’, assigns(:id).status
end
Hey,
thanks again for the help, I’ve given it another one but come up with
pretty much the same errors. (side note the strings I was asserting to
are now symbols)
def test_should_delete_word
assert_equal :published, words(:one).status
delete :destroy, :id => words(:one).to_param
reload!
word_status = Word.find(:id).status
assert_equal :deleted, word_status
end
Again returns: MethodError: undefined method `reload!’ for
#WordsControllerTest:0x2858368
I also tried reloading on the active record object directly
def test_should_delete_word2
assert_equal :published, words(:one).status
delete :destroy, :id => words(:one).to_param
words(:one).reload (as well as reload!)
word_status = Word.find(:id).status
assert_equal :deleted, word_status
end
It returns: ActiveRecord::RecordNotFound: Couldn’t find Word with
ID=id
Eventually it worked with(just a last attempt before I posted):
Which I find a little weird. Just because in this and other tests I’ve
found the fixtures produce weird id’s when they hit the db. The only
way I can find matching id’s is with the to_param string. So why
Word.find(words(:one)) managed to find a matching ID in the db without
using to_param beats me.
But thanks for everyones input ! If you have any idea about the id’s I
wouldn’t mind understanding exactly what is going on there.
Which I find a little weird. Just because in this and other tests I’ve
found the fixtures produce weird id’s when they hit the db. The only
way I can find matching id’s is with the to_param string. So why
Word.find(words(:one)) managed to find a matching ID in the db without
using to_param beats me.
because find knows the right thing to do if you give it an
activerecord object.
You can do either words(:one).reload and then look at words
(:one).status or look at Word.find(words(:one)).status but you don’t
need to do both - that’s just redundant.
using:
assert_equal :published, words(:one).status
delete :destroy, :id => words(:one).to_param
word_status = Word.find(:id).status
assert_equal :deleted, word_status
still returns // ActiveRecord::RecordNotFound: Couldn’t find Word with
ID=id
Fred,
I see what you mean now. If I wanted to pull the information from the
db instead of the fixture then there was no point in taking the time
to reload the stale fixture. Now that we’ve reloaded it I can feel
free to test against then fresh data.
This function now passes without problem and it makes sense:
def test_should_delete_word
assert_equal :published, words(:one).status
delete :destroy, :id => words(:one).to_param
words(:one).reload
assert_equal :deleted, words(:one).status
end