I'm probably missing some basic Ruby syntax, but I'm relatively new to
Ruby and can't figure this out from the various references I've looked
at
I'd like to use this nifty test helper:
# Calls creation_method with nil values for field_names and asserts
that
# the resulting object was not saved and that errors were added for
that field.
#
# assert_required_fields :create_article, :subject, :body, :author
def assert_required_fields(creation_method, *field_names)
field_names.each do |field|
record = send(creation_method, field => nil)
assert_equal false, record.valid?
assert_not_nil record.errors.on(field)
end
end
However, I don't know how to pass the creation method. My basic test
would be:
def test_should_create_user
user = User.create(:email => "fred@foo.com", :lastname => "jones",
:password => "secret");
assert user.valid?, "User was invalid:\n#{user.to_yaml}"
end
I tried this for the failure case...
def test_should_not_create_user_unless_default_fields
assert_required_fields User::create, :email, :lastname, :password
end
But that reports an error:
1) Error:
test_should_not_create_user_unless_default_fields(UserTest):
TypeError: #<User uuid: nil, firstname: nil, lastname: nil, login: nil,
email: nil, ...> is not a symbol
Can someone advise me of the correct syntax?
Thanks,
Sarah
on 02.03.2009 10:50
on 02.03.2009 11:27
> assert_required_fields User::create, :email, :lastname, :password
Instead of User::create, which doesn't return the method as it would
in some other languages but calls it right away, you could use either
one of:
User.method(:create)
lambda {|*args| User.create(*args)}
HTH
on 02.03.2009 11:32
Hi Leo,
This gave me the same error:
assert_required_fields User.method(:create), :email, :lastname,
:password
I got a different error with this:
assert_required_fields {|*args| User.create(*args)}, :email, :lastname,
:password
test/unit/user_test.rb:15: syntax error, unexpected ',', expecting kEND
assert_required_fields {|*args| User.create(*args)}, :email,
:lastname, :password
Am I missing something?
Thanks,
Sarah
on 02.03.2009 11:36
On Mon, Mar 2, 2009 at 6:49 PM, Sarah Allen <sarah@ultrasaurus.com> wrote: > Â # > Â # Â assert_required_fields :create_article, :subject, :body, :author > Â def assert_required_fields(creation_method, *field_names) > Â Â field_names.each do |field| > Â Â Â record = send(creation_method, field => nil) > Â Â Â assert_equal false, record.valid? > Â Â Â assert_not_nil record.errors.on(field) > Â Â end > Â end ## Using blocks: def assert_required_fields(*field_names, &block) field_names.each do |field_name| record = yield(field_name => nil) assert_equal(false, record.valid?) assert_not_nil(record.errors.on(field) end end # Usage: assert_required_fields(:email, :lastname, :password){|field| User::create(field) } ## Using the method itself def assert_required_fields(method, *field_names) field_names.each do |field_name| record = method.call(field_name => nil) assert_equal(false, record.valid?) assert_not_nil(record.errors.on(field) end end # Usage assert_required_fields(User.method(:create), :email, :lastname, :password) ## Using send def assert_required_fields(obj, method, *field_names) field_names.each do |field_name| record = obj.send(method, field_name => nil) assert_equal(false, record.valid?) assert_not_nil(record.errors.on(field) end end # Usage assert_required_fields(User, :create, :email, :lastname, :password) ^ manveru
on 02.03.2009 11:45
Wow. Awesome run through of various Ruby syntax options -- I think I'll print that out and hang it on my wall. Oddly none of those match the original definition which uses send but has just a single "creation_method" parameter... >> Â # Â assert_required_fields :create_article, :subject, :body, :author >> Â def assert_required_fields(creation_method, *field_names) >> Â Â field_names.each do |field| >> Â Â Â record = send(creation_method, field => nil) >> Â Â Â assert_equal false, record.valid? >> Â Â Â assert_not_nil record.errors.on(field) >> Â Â end >> Â end Any thoughts on how that could be called? Thanks, Sarah
on 02.03.2009 11:56
On Mon, Mar 2, 2009 at 7:44 PM, Sarah Allen <sarah@ultrasaurus.com> wrote: >>> Â Â Â assert_not_nil record.errors.on(field) >>> Â Â end >>> Â end > > Any thoughts on how that could be called? It's the second example, you cannot obtain an instance of Method like you would do in Python or JavaScript by simply omitting the parenthesis, you have to use the Object#method method. All of these are equivalent: User.create User.create() User.method(:create).call User.send(:create) ^ manveru
on 02.03.2009 16:17
Michael Fellinger wrote: > On Mon, Mar 2, 2009 at 7:44 PM, Sarah Allen <sarah@ultrasaurus.com> > wrote: >>>> Â Â Â assert_not_nil record.errors.on(field) >>>> Â Â end >>>> Â end >> >> Any thoughts on how that could be called? > > It's the second example, you cannot obtain an instance of Method like > you would do in Python or JavaScript by simply omitting the > parenthesis, you have to use the Object#method method. > > All of these are equivalent: > > User.create > User.create() > User.method(:create).call > User.send(:create) > > ^ manveru I get the error: (ActiveRecord::Base).create> is not a symbol calling: assert_required_fields User.method(:create), :create, :email, :lastname, :password the code in my library uses send, not call Of course, I could just change the definition of assert_required_fields, but since it is part of a plugin (http://topfunky.net/svn/plugins/topfunky_power_tools/lib/topfunky/test_helper.rb ), I figure there must be some standard way to call it Thanks for your help, Sarah
on 02.03.2009 17:30
On Tue, Mar 3, 2009 at 12:16 AM, Sarah Allen <sarah@ultrasaurus.com> wrote: >> you would do in Python or JavaScript by simply omitting the > > I get the error: (ActiveRecord::Base).create> is not a symbol > calling: > Â assert_required_fields User.method(:create), :create, :email, > :lastname, :password Sorry, with rails all bets on normally behaving ruby code are off. ^ manveru
on 02.03.2009 19:07
On Mon, Mar 2, 2009 at 10:16 AM, Sarah Allen <sarah@ultrasaurus.com> wrote: > > you would do in Python or JavaScript by simply omitting the > > http://topfunky.net/svn/plugins/topfunky_power_tools/lib/topfunky/test_helper.rb > ), I figure there must be some standard way to call it Yes, you need to pass a symbol, just as the error is trying to tell you: def test_should_not_create_user_unless_default_fields assert_required_fields :create, :email, :lastname, :password end I'm assuming that this is in the unit test for the User model. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale
on 02.03.2009 19:42
Rick Denatale wrote: > Yes, you need to pass a symbol, just as the error is trying to tell you: > > def test_should_not_create_user_unless_default_fields > assert_required_fields :create, :email, :lastname, :password > end > > I'm assuming that this is in the unit test for the User model. So, how would it magically know to call create on User and not some other class? as I might expect, I get this error: 1) Error: test_should_not_create_user_unless_default_fields(UserTest): NoMethodError: undefined method `create' for #<UserTest:0x1e93a58> Thanks, Sarah:w
on 02.03.2009 21:18
On Mon, Mar 2, 2009 at 1:41 PM, Sarah Allen <sarah@ultrasaurus.com> wrote: > other class? as I might expect, I get this error: > > 1) Error: > test_should_not_create_user_unless_default_fields(UserTest): > NoMethodError: undefined method `create' for #<UserTest:0x1e93a58> > Okay, I'm curious where you found the topfunky power tools plugin. There's not much that google reveals about the usage. However, it appears to come from a very early Peepcode screen cast on Test First Design (Peepcode #4 to be exact). I did a quick look at the screencast and it depends on having helper method called ceate in the test case. So you should have something like: class UserTest < Test::Unit::TestCase #... def test_should_not_create_user_unless_default_fields assert_required_fields :create, :email, :lastname, :password end private def create(options={}) User.create({ :email => "fred@foo.com", :last_name => "jones", :password => "secret" }.merge(options) ) end end The create method creates a valid record, and the assert_required_fields nils out each field asserted to be required, calls the create method with that field set to nil and ensures that the resulting record has an error on that field. And given that helper method, the other test can be re-written as: def test_should_create_user user = create assert user.valid?, "User was invalid:\n#{user.to_yaml}" end Now, as I say, this plugin doesn't seem to be very popular based on a google search, and it's rather old. There are probably more 'modern' approaches to testing required field validations these days using Test::Unit tests in Rails, I'm not as up on that as I tend to use RSpec rather than Test::Unit. And since this really IS a Rails question, it probably would have gotten a better response, quicker if it had been submitted ot the ruby on rails mailing list. -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale
on 02.03.2009 21:23
On Mar 2, 2009, at 3:16 PM, Rick DeNatale wrote: > Okay, I'm curious where you found the topfunky power tools plugin. > There's > not much that google reveals about the usage. > > However, it appears to come from a very early Peepcode screen cast > on Test > First Design (Peepcode #4 to be exact). I did a quick look at the > screencast and it depends on having helper method called ceate in > the test > case. So you should have something like: Wow. +10 to Rick for his google-ruby-rails-test-unit-mentoring-fu Gary Wright
on 02.03.2009 22:20
Rick Denatale wrote: > Okay, I'm curious where you found the topfunky power tools plugin. > There's not much that google reveals about the usage. I'm just getting into TDD. I experimented with cucumber a bit and really liked it, but I'm diving into an old codebase with lots of pre-existing unit tests. I wanted to understand the basics, so (as you guessed) I bought the peepcode tutorial. > Now, as I say, this plugin doesn't seem to be very popular based on a > google search, and it's rather old. There are probably more 'modern' > approaches to > testing required field validations these days using Test::Unit tests in > Rails, I'm not as up on that as I tend to use RSpec rather than > Test::Unit. If its wisdom is out of date, is there another resource you recommend? Or is everyone just skipping unit tests these days in favor of the BDD tools? > And since this really IS a Rails question, it probably would have gotten > a better response, quicker if it had been submitted ot the ruby on rails > mailing list. Yeah, I see that in retrospect -- seemed like a basic language question at the time. Thanks so much for digging in and letting me know the scoop, which I clearly didn't fully understand from the screencast. Of course, now I know four ways to pass a method as a parameter, which is fabulous. Cheers, Sarah