How can I get Factory Girl to NEVER hit the database if I am calling Factory.build in order to make my controller tests FAST? How can I get Factory Girl to NEVER hit the database if I am calling Factory.build in order to make my controller tests FAST? ruby ruby

How can I get Factory Girl to NEVER hit the database if I am calling Factory.build in order to make my controller tests FAST?


Well, I guess I will answer my own question. I think it's the right answer, and maybe others can learn from it as I had to spend a few hours to learn it.

Here's how I got a 2000% (or 20x) speed improvement:

before(:each) do  @user = User.new  controller.stub(:authenticate_user!)  controller.stub(:current_user).and_return(@user)  controller.stub(:add_secure_model_data)  @site_update = SiteUpdate.new  @comment = Comment.newend

The solution is simply not to use Factories of any kind for controller tests (and perhaps other kinds of tests). I suggest only use Factory's when it is too much of a pain in the ass to do otherwise.

All 3 tests now run in 0.07 seconds! Before it was 1.4 seconds to run all 3 tests.

Factory_girl is simply a terribly slow library. I don't know what the heck it is doing, but it is not profiled properly.

Yes, I know it's doing a lot more than simple MyClass.new statements... but even for a slower scripting language like Ruby, the performance is many orders of magnitude slower than basic class instantiation. It needs to undergo some massive optimization so that Factory.build(:my_class) is brought more in line with MyClass.new

I would suggest to the implementers of Factory_girl to try and get it so that it's overhead is not much slower than a basic MyClass.new call (excluding database overhead... that can't be avoided). It should provide a nice way to build objects and you shouldn't have to pay a 20x performance penalty to get this benefit. That's not an acceptable trade-off.

This is all really too bad, because Factory.build would be nice in controllers when you have render_views turned on inside of your controller specs. There should be significant motivation to correct this.

In the meantime, just use basic Ruby/Rails classes. I think you'll be amazed how fast they actually are....


I had the same problem as @FireEmblem and eventually narrowed the issue down to FactoryGirl.build. FactoryGirl.stub didn't make things any better.

I finally realized it's because one of my models had validation logic that made an HTTP request when a certain field was present. The factory put a value in that field, so on the outside, it looked like FactoryGirl was slowing down my tests. In reality, it was, but only because it triggered the HTTP request. Removing one line from one of my factories eliminated the HTTP request, causing a 60x performance improvement.