While writing Rails apps, I've written several variants on the 'give me an ActiveRecord instance that can't talk to the DB' theme over the last couple of years while writing tests or specs for an app. The basic pattern is a pretty good one - it guarantees you a certain degree of test isolation for your unit tests or specs, when you need it. And, because you're make specific instances isolated, you can get to the DB if you need to.
I've done it enough times now that I wound up making a plugin to share the code between projects. As time has gone on, I've wanted something a bit more declarative too, so that I could make sensible statements about the intended validity or newness of the object, since I've often found myself using it in concert with mocking and stubbing. It's quite nice to be able to ask for an invalid instance without having to worry about setting or not setting the right fields to get a valid or invalid object. Often, it's enough to know that .valid? will fail. So, with my ModelMocker plugin, you can do things like this:
>> mock_object = ModelClass.mock { |m| m.as_new_record }
>> mock_object.new_record?
=> true
Or,
>> mock_object = ModelClass.mock do |m|
?> m.as_new_record
?> m.invalid
?> end
>> mock_object.new_record?
=> true
>> mock_object.valid?
=> false
And, in a slight twist:
>> mock_object = ModelClass.mock(:id => 123, :other_attr => "value")
>> mock_object.new_record?
=> false
>> mock_object.id
=> 123
Being able to specify the id is very useful, and I always found myself wanting ActiveRecord objects with IDs to act like they were fetched from the DB, so I made setting this (mock) ID imply that the object should behave like a saved one.
The plugin is available from GitHub, and is installed (with a Rails that can install plugins from Git) with:
./script/plugin install git://github.com/fidothe/model_mocker.git
The only setup you need to do is to require model_mocker' in your spec_helper.rb (or somewhere equivalent).
ModelMocker's RDoc is on reprocessed.org, as well as being installed with the plugin.