Function Testing Reloading Fixtures before assertion

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’

//Controller:
def destroy
@word = Word.find(params[:id], :include => :definitions)
@word.status = ‘deleted’
@word.save

@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.

Any help would be appreciated.

  • bp

On Sep 1, 9:41 pm, brianp [email protected] wrote:

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

Frederick C. wrote:

On Sep 1, 9:41�pm, brianp [email protected] wrote:

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.

Best,

Marnen Laibow-Koser
http://www.marnen.org
[email protected]

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.

Fred

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

def test_should_delete_word
assert_equal ‘published’, words(:one).status
debugger
delete :destroy, :id => words(:one).to_param
Word.reload
word_status=Word.find(:id).status
assert_equal ‘deleted’, word_status
end


nik

Returns reload is not method.

sorry for wrong syntax

it must be
reload!

you are using Word.find(:id.to_param).status in assert instead of that
use
“Word.find_by_user_id(1).status” ( as per your fixture in first
post)

def test_should_delete_word
assert_equal ‘published’, words(:one).status
delete :destroy, :id => words(:one).to_param
reload!
word_status=Word.find_by_user_id(1).status
assert_equal ‘deleted’, word_status
end

Hey everyone thanks for the input.

I’ve tried your suggestions with varying results:

def test_should_delete_word
assert_equal ‘published’, words(:one).status
debugger
delete :destroy, :id => words(:one).to_param
Word.reload
word_status=Word.find(:id).status
assert_equal ‘deleted’, word_status
end
Returns reload is not method.

I tried
def test_should_delete_word2
assert_equal ‘published’, words(:one).status
delete :destroy, :id => words(:one).to_param

  assert_equal 'deleted', Word.find(:id.to_param).status

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

Thanks for your suggestions so far

On Sep 3, 1:20 am, brianp [email protected] wrote:

assert_equal 'deleted', word_status

end
Returns reload is not method.

reload is a method on an individual activerecord object (ie words
(:one).reload)

Fred

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

def test_should_delete_word2
assert_equal :published, words(:one).status
delete :destroy, :id => words(:one).to_param
words(:one).reload
word_status = Word.find(words(:one)).status
assert_equal :deleted, word_status
end

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.

-bp

On Sep 3, 12:41 am, Frederick C. [email protected]

On Sep 3, 9:22 am, brianp [email protected] wrote:

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

That doesn’t make a whole load of sense - unless there had been a word
whose id was the string id.

words(:one).reload
word_status = Word.find(words(:one)).status
assert_equal :deleted, word_status

end

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.

Fred

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

remove reload!

 assert_equal :published, words(:one).status
 delete :destroy, :id => words(:one).to_param
 word_status = Word.find(:id).status
 assert_equal :deleted, word_status

nilk_cse

Nilesh,

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

Again thanks everyone for your input !

On Sep 3, 1:50 am, Nilesh K. [email protected]

brianp wrote:

Nilesh,

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

don’t use :id use
Word.find_by_use user_id(1)

Nilesh