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
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
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)
- 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
Here's a test that checks we allow a user to sign up:
user = assert_latest User do
create_user(:login => ‘phlip’)
assert_equal ‘phlip’, user.login
(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
deny_latest User do
create_user(:login => nil)
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.