Finally fixed this and I hope I can save someone the six hours of debugging it took me to figure it out.
By a) getting lucky and ending up with a version of code that worked and b) stripping both sets of code down this is what I found:
Test that chokes up
require 'spec_helper'
describe UsersController do
@user = Factory.create(:user)
end
Test that works
require 'spec_helper'
describe UsersController do
it "should make a factory models without choking" do
@user = Factory.create(:user)
end
end
The transaction is defined by the it “should do something” do… statement. If you instantiate the factory outside that statement it turns out not to be transactional.
You can also put it outside the “it should..” block as long as it’s in a “before..end” block
require 'spec_helper'
describe UsersController do
before(:each) do
@user = Factory.create(:user)
end
it 'should make a factory without choking' do
puts @user.name
# prints out the correnct name for the user
end
end
On experimenting, it seems to be valid to define a user outside of an “it should do..end” block as long as it’s in a “before.. end” block. I guess this is only executed in the scope of the “it should do..end” block and therefore works fine.
[Thanks to @jdl for his (also correct) suggestion]