Railsters: A recent question here asked how to get the ID of a recently added Model object. (The answer is that methods like .create and .save populate the .id field.) This leads to a new question: How can a test detect the most recently added record? The best way is for "unit test" code to directly call methods who create the record, and they should return it. Sometimes that''s not so easy. Controller tests, for example, only return their @ instance variables in their assigns[] hash, and a controller that creates model objects might not have a good reason to assign and remember them. To cover these situations (and to respond to several needs in my current project), I invented two new assertions: - assert_latest(Model, message = nil, &block) - deny_latest(Model, message = nil, &block) Both take... - Model - an ActiveRecord class, such as User, Chat, etc... - message - optional string to prefix any flunk messages - block - a required closure to call the tested code The assert_ passes, and the deny_ fails, if any new record got created in that Model. Here''s a test that checks we allow a user to sign up: def test_should_allow_signup user = assert_latest User do create_user(:login => ''phlip'') assert_response :redirect assert_redirected_to ''http://test.host/phlip'' end assert_equal ''phlip'', user.login end (Heck - my programs had better allow /me/ to sign up!!) And here''s code to prevent a bogus signup attempt from creating a new User record: def test_should_require_login_on_signup deny_latest User do create_user(:login => nil) assert assigns(:user).errors.on(:login) assert_response :success end end Below my sig is a bio-plugin. Simply copy it into your test_helper.rb file, inside its main class there, and add assert_latest and deny_latest to every test that creates something - or should not! Note that the code could not simply find the highest ID currently in use and simply add 1. A database table remembers an internal "Max ID" value, and always increments this. Other test cases may create and delete records; each bumps this "high water mark" up. So the implementation must find the lowest new ID that''s higher than the maximum stored in any record. The committee would be interested to hear if any rare arcane databases out there fail this system. -- Phlip http://www.oreilly.com/catalog/9780596510657/ "Test Driven Ajax (on Rails)" assert_xpath, assert_javascript, & assert_ajax def assert_latest(model, message = nil, &block ) return get_latest(model, &block) || flunk_latest(model, message, true) end def deny_latest(model, message = nil, &block) get_latest(model, &block) and flunk_latest(model, message, false) end def get_latest(model) max_id = model.maximum(:id) yield return model.find( :first, :conditions => "id > #{max_id}", :order => "id desc" ) end def flunk_latest(model, message, polarity) message = if message then "#{message}\n" else '''' end message += ''a new '' message += model.name message += '' record should '' message += ''not '' unless polarity message += ''be created'' flunk(message) end --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group. To post to this group, send email to rubyonrails-talk-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org To unsubscribe from this group, send email to rubyonrails-talk-unsubscribe-/JYPxA39Uh5TLH3MbocFFw@public.gmane.org For more options, visit this group at http://groups.google.com/group/rubyonrails-talk?hl=en -~----------~----~----~----~------~----~------~--~---