Another test question

fairly simple actually.

CaseManager has_many :clients
Client belongs_to :case_manager

test/unit/case_manager.rb

fixtures :case_managers

def setup
@case_manager = CaseManager.find(7)
end

Replace this with your real tests.

def test_truth
assert_kind_of CaseManager, @case_manager
end

and when I run this test, I get this error…

  1. Error:
    test_truth(CaseManagerTest):
    ActiveRecord::StatementInvalid: PGError: ERROR: update or delete on
    “case_managers” violates foreign key constraint “fk_cp_case_manager” on
    “clients”
    DETAIL: Key (id)=(3) is still referenced from table “clients”.
    : DELETE FROM case_managers

Which sort of makes sense in that I can’t delete a case_manager that has
an active client but in case_managers.yml, case_manager.id = 7 is
specifically created as to not having any clients in clients.yml

Shouldn’t ‘assert_kind_of CaseManager, @case_manager’ just test only
this one case_manager from case_managers.yml?

Craig

Craig W. wrote:

test/unit/case_manager.rb

Gotta name that case_manager_test.rb, so the tools don’t go looking
around for it.

You might want to start again, using script/generate model case_manager,
so the
generator creates everything you need, in the right places.

fixtures :case_managers

Also pull in , :clients - specifically because you don’t need it.

ActiveRecord::StatementInvalid: PGError: ERROR: update or delete on
“case_managers” violates foreign key constraint “fk_cp_case_manager” on
“clients”
DETAIL: Key (id)=(3) is still referenced from table “clients”.
: DELETE FROM case_managers

The fixtures line starts by deleting everything in case_managers. But
because
one is bonded to a pre-existing clients, you can’t delete it.

So tell fixtures to also delete the clients, by pulling in their
fixtures.

If the code still won’t work, look up fixtures_load_order, and force the
fixtures to load things in the right order for destruction.

If that still doesn’t work, take out a foreign_key constraint! They
naturally
can’t form a closed cycle…


Phlip

On Sun, 2008-05-25 at 11:01 -0700, Phlip wrote:

Craig W. wrote:

test/unit/case_manager.rb

Gotta name that case_manager_test.rb, so the tools don’t go looking around for it.


sorry…my mistake…it was named properly

fixtures :case_managers

Also pull in , :clients - specifically because you don’t need it.


I did add it in there wondering about that but order is so
important…it had to be ‘after’ I loaded the case_managers fixtures.

So tell fixtures to also delete the clients, by pulling in their fixtures.

If the code still won’t work, look up fixtures_load_order, and force the
fixtures to load things in the right order for destruction.

If that still doesn’t work, take out a foreign_key constraint! They naturally
can’t form a closed cycle…


I did get it to work as you suggested…by adding fixtures :clients and
adding it after fixtures :case_managers instead of before. Obviously I
don’t want to delete the various foreign key constraints in PostgreSQL
in the event the tables are manipulated by other client applications.

Thanks…I’m learning slowly. I’ve been going through my AWDWR on
testing (which I know is somewhat flawed), the manuals.rubyonrails.org
web pages and have studied the beast code as you suggested. I could tell
that assert_kind_of was trying to delete each record but none of these
things actually fully explains what each of these assertions actually do
(and I recognize that they are part of Ruby base and not Rails).

By the way…installing mocha plugin pretty much broke the tests that I
have gotten to work so far so I removed it. It seems that mocha requires
a little better understanding of tests than I’ve achieved so far.

Thanks for the help

Craig

If the code still won’t work, look up fixtures_load_order, and force the

I did get it to work as you suggested…by adding fixtures :clients and
adding it after fixtures :case_managers instead of before. Obviously I
don’t want to delete the various foreign key constraints in PostgreSQL
in the event the tables are manipulated by other client applications.

Did you set the fixtures_load_order like I said?

And if you want to make a database different from your production one,
you can
simply refrain from migrating when you deploy.

Before you start a test run, your test database (not the production
one)
should have nothing in it.

Thanks…I’m learning slowly. I’ve been going through my AWDWR on
testing (which I know is somewhat flawed), the manuals.rubyonrails.org
web pages and have studied the beast code as you suggested. I could tell
that assert_kind_of was trying to delete each record but none of these

assert_kind_of does not delete things!

By the way…installing mocha plugin pretty much broke the tests that I
have gotten to work so far so I removed it. It seems that mocha requires
a little better understanding of tests than I’ve achieved so far.

It certainly does not; it should have just silently started working.
Only when
you require it and add .expects to a class will it actually do anything.

Please post your error message, because something else is going on.

And if you want to make a database different from your production one, you can
simply refrain from migrating when you deploy.

Another fix here: All your migrations actually create views. These
rename the
real database tables and fields to things fitting ActiveRecord’s
official
opinions. Then all your migrations never touch the real database tables.

You’d need to use some form of connection.execute, because I don’t think
any AR
migration methods can create views.

On Sun, 2008-05-25 at 12:23 -0700, Phlip wrote:

If the code still won’t work, look up fixtures_load_order, and force the

I did get it to work as you suggested…by adding fixtures :clients and
adding it after fixtures :case_managers instead of before. Obviously I
don’t want to delete the various foreign key constraints in PostgreSQL
in the event the tables are manipulated by other client applications.

Did you set the fixtures_load_order like I said?


No - I’ve been unable to find anything useful on ‘fixtures_load_order’
from googling. I have sort of gotten the idea of order.

And if you want to make a database different from your production one, you can
simply refrain from migrating when you deploy.

Before you start a test run, your test database (not the production one)
should have nothing in it.


my test database tables seem to retain the data being loaded by the
fixtures files.

Thanks…I’m learning slowly. I’ve been going through my AWDWR on
testing (which I know is somewhat flawed), the manuals.rubyonrails.org
web pages and have studied the beast code as you suggested. I could tell
that assert_kind_of was trying to delete each record but none of these

assert_kind_of does not delete things!


I got it now…it was the reloading of the case_managers fixtures that
was the problem because it was trying to delete the existing
case_managers which caused an issue for existing clients.

By the way…installing mocha plugin pretty much broke the tests that I
have gotten to work so far so I removed it. It seems that mocha requires
a little better understanding of tests than I’ve achieved so far.

It certainly does not; it should have just silently started working. Only when
you require it and add .expects to a class will it actually do anything.

Please post your error message, because something else is going on.


I want to get through unit testing first…I have a number of models and
I think I am getting it but it is coming slowly.

Craig

No - I’ve been unable to find anything useful on ‘fixtures_load_order’
from googling. I have sort of gotten the idea of order.

How are you Googling? I get this line…

ActiveRecord::Base.configurations[:fixtures_load_order]

…in every single hit - it’s exactly what we use at work.

my test database tables seem to retain the data being loaded by the
fixtures files.

For each fixture you name in fixtures(), the table is first completely
erased. Then the data are dumped in from the yml file.

On Sun, 2008-05-25 at 13:12 -0700, Phlip wrote:

No - I’ve been unable to find anything useful on ‘fixtures_load_order’
from googling. I have sort of gotten the idea of order.

How are you Googling? I get this line…

ActiveRecord::Base.configurations[:fixtures_load_order]

…in every single hit - it’s exactly what we use at work.


OK - gotcha…I ended up putting it into environments/test.rb just to be
safe - I suppose that this will simplify my life.

my test database tables seem to retain the data being loaded by the
fixtures files.

For each fixture you name in fixtures(), the table is first completely
erased. Then the data are dumped in from the yml file.


OK - got it. I noticed beast uses ‘all fixtures’ instead of naming each
one.

Thanks

Craig

OK - got it. I noticed beast uses ‘all fixtures’ instead of naming each
one.

Bleah - I hate that style.

However, my colleagues hate hitting mysterious goofy bugs in our test
cases,
which change their aspects depending on which kind of test batch we run.
I
always just notice we are missing a fixture and I add it.

To each his or her own! (-;

On 26 May 2008, at 07:11, Craig W. wrote:

at 2008-05-25 23:09:13) [POST]
Session ID:
Parameters:
{“action”=>“controllerloginuserloginadminpasswordADMINactionlogin”,
“controller”=>“case_managers”}

How do I get the authentication passed to the login controller?

You can’t. With a functional test you only interact with one
controller. Just set the session to simulate a user being logged in.

Fred

On Mon, 2008-05-26 at 11:11 +0100, Frederick C. wrote:

Processing
You can’t. With a functional test you only interact with one
controller. Just set the session to simulate a user being logged in.


I’m googling around but not finding something that works here…this is
what I’m trying:

session = ActionController::TestSession.new
@authuser = User.find 1
session[:user_id] = @authuser.id
session[:user_name] = @authuser.name

do I have to pass session[:user_id] with each request?

Craig

On Sun, 2008-05-25 at 22:29 -0700, Phlip wrote:

OK - got it. I noticed beast uses ‘all fixtures’ instead of naming each
one.

Bleah - I hate that style.

However, my colleagues hate hitting mysterious goofy bugs in our test cases,
which change their aspects depending on which kind of test batch we run. I
always just notice we are missing a fixture and I add it.

To each his or her own! (-;


you’re the one who suggested I study the ‘beast’ style of testing :wink:

Anyway…I have an issue that has me perplexed…

I put my login method in test_helper.rb (per suggestion of AWDWR)…

def login_with_reception(login=‘admin’, password=‘ADMIN’)
post :login, :user => { :login => login, :password => password }
assert_not_nil(session[:user_id])
user = User.find(session[:user_id])
assert_equal ‘Low Level User’, user.name
end

(the above code works in test/functional/users_controller_test.rb)

When I call the code in
test/functional/case_managers_controller_test.rb, via
login_with_reception(), it always tries to find the ‘login’ method in
case_managers_controller.rb which of course doesn’t exist because
‘login’ method is in login_controller.rb

I added ‘require login_controller’ at the top of
case_managers_controller_test.rb but it doesn’t make a difference.

I also tried changing it to…
post :controller => ‘login’, :action => ‘login’, :user =>
{ :login => login, :password => password }

but it still passes the entire thing to the case_managers_controller
with one long string error…
Processing
CaseManagersController#controllerloginuserloginadminpasswordADMINactionlogin
(for 0.0.0.0 at 2008-05-25 23:09:13) [POST]
Session ID:
Parameters:
{“action”=>“controllerloginuserloginadminpasswordADMINactionlogin”,
“controller”=>“case_managers”}

How do I get the authentication passed to the login controller?

Craig

On Mon, 2008-05-26 at 16:00 +0100, Frederick C. wrote:

post :controller => ‘login’, :action => ‘login’, :user =>
{“action”=>“controllerloginuserloginadminpasswordADMINactionlogin”,
All i do is
@request.session[:user_id] = 1
if you need to set other stuff in your session then do that.
I usually stick that in the setup method, at the bottom (don’t forget
to call super first). You might want to wrap that up into a
log_user_in method in test_helper.rb


I just got it by googling but pretty much the same as you wrote…

@authuser = User.find 1
@request.session[:user_id] = @authuser.id
@request.session[:user_name] = @authuser.name

What Class do I want to super?

Thanks

Craig

On 26 May 2008, at 15:20, Craig W. wrote:

but it still passes the entire thing to the case_managers_controller
How do I get the authentication passed to the login controller?

You can’t. With a functional test you only interact with one
controller. Just set the session to simulate a user being logged in.


I’m googling around but not finding something that works here…this
is what I’m trying:

All i do is
@request.session[:user_id] = 1
if you need to set other stuff in your session then do that.
I usually stick that in the setup method, at the bottom (don’t forget
to call super first). You might want to wrap that up into a
log_user_in method in test_helper.rb

Fred

On 26 May 2008, at 16:06, Craig W. wrote:

@authuser = User.find 1
@request.session[:user_id] = @authuser.id
@request.session[:user_name] = @authuser.name

What Class do I want to super?

That’s a nonsensical method. In rails 2.0, your functional tests
inherit from ActionController::TestCase which provides a setup method
which creates the test request, instantiates the controller and so on.
If you just define your setup method then you need to call super so
that setup happens ( in 2.1 this is no longer necessary)
So your setup method should look ike

def setup
super
#mess around with the session
end

Fred


First off…I’m still on 1.2.6 but always have an eye on Rails 2.x

secondly, I need to test RBAC for various users and my ‘layouts’
need session[:user_name] or they’ll toss an error but my
before_filter requires session[:user_id]

fair enough. Still seems a little redundant since you’ve got the user
id.

def test_new
assert_not_nil assigns(:case_manager)

the third piece of this test_method fails in authorization filter
which is why I want to test like this.

Am I missing something here?

the answer is probably hidden in your login_with_reception method.
It’s also a bit naughty having more than one request per test case.

Fred

On Mon, 2008-05-26 at 16:23 +0100, Frederick C. wrote:

log_user_in method in test_helper.rb
inherit from ActionController::TestCase which provides a setup method
which creates the test request, instantiates the controller and so on.
If you just define your setup method then you need to call super so
that setup happens ( in 2.1 this is no longer necessary)
So your setup method should look ike

def setup
super
#mess around with the session
end


First off…I’m still on 1.2.6 but always have an eye on Rails 2.x

secondly, I need to test RBAC for various users and my ‘layouts’ need
session[:user_name] or they’ll toss an error but my before_filter
requires session[:user_id]

thus I have gotten to work
test/functional/case_managers_controller/test.rb…

…snipping the top
def setup
@controller = CaseManagersController.new
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
end

def test_new
login_with_administrator
get :new
assert_response :success
assert_template ‘new’
assert_not_nil assigns(:case_manager)

login_with_privileged
get :new
assert_response :success
assert_template 'new'
assert_not_nil assigns(:case_manager)

login_with_reception
get :new
assert_response 302
assert_response :redirect
assert_redirected_to :action => 'list'

end

and login_with_… sets the session[:user_id] and session[:user_name]
values

the third piece of this test_method fails in authorization filter which
is why I want to test like this.

Am I missing something here?

Craig

To each his or her own! (-;

you’re the one who suggested I study the ‘beast’ style of testing :wink:

Using all_fixtures (or whatever they use) does not cause problems with
the rest
of their testage. They could make a symetric change, and replace all the
all_fixtures with the exact set of fixtures used in each suite, and the
rest of
the (exemplary) test cases would still run correctly.

In general, expensive setup is a design smell. That includes pulling
every
fixture in your app into a unit test suite. Why is that tested unit so
coupled
to everything else?

Beast probably does not have that problem because they are probably not
coupled.
Use of all_fixtures did not trick them into coupling all their code! But
the
reverse situation - carefully selecting which fixture goes in what suite

  • is
    one of the forces that can keep units decoupled.

(the above code works in test/functional/users_controller_test.rb)

That sucks. Just stuff the user you need into session[:user_id], without
a
round-trip thru post.

When I call the code in
test/functional/case_managers_controller_test.rb, via
login_with_reception(), it always tries to find the ‘login’ method in
case_managers_controller.rb which of course doesn’t exist because
‘login’ method is in login_controller.rb

It also sucks because post can only hit the current controller. There’s
never a
reason to thwart this; each functional test suite should only hit one
controller.

I added ‘require login_controller’ at the top of
case_managers_controller_test.rb but it doesn’t make a difference.

That’s not how to bond classes. If you actually did that, you would need
class
CaseManagersController < LoginController. Don’t do that, because it
would dump
every method of LoginController - including many pregenerated ones you
can’t see

  • into CaseManagersController. I doubt such an app would even launch
    correctly.

In general, never tangle up your production code just to appease a
test case.

Use Google Codesearch and find “def login_as”. Then match that up with
what you
are doing. That method typically just stuffs the user you need into the
sessions.

You will get the best benefit out of AWDWR when you start questioning
everything
it does! (-;


Phlip