4

I want to use FactoryGirl to build in-memory stubs of models, then have all ActiveRecord queries run against only those. For example:

# Assume we start with an empty database, a Foo model, 
# and a Foo factory definition.

#foo_spec.rb
stubbed_foo = FactoryGirl.build_stubbed(:foo)

# Elsewhere, deep in the guts of application
Foo.first() # Ideally would return the stubbed_foo we created
            # in the test. Currently this returns nil.

The solution might be to use an in-memory database. But is the above scenario possible?

3
  • If you don't have any tables, then there's no schema for models to follow, so your stubbed model could behave like any object without having to match with the actual schema that will exist in production. This would probably be a bad idea. Why are you trying to bypass ActiveRecord in this way? Commented Feb 4, 2017 at 18:31
  • You could use fixtures instead of factory girl Commented Feb 4, 2017 at 18:56
  • @trueinViso I don't think fixtures would solve my problem, as the Foo class would still go to the database when calling first() or any other query method. Commented Feb 5, 2017 at 20:20

1 Answer 1

1

If your reason for avoiding the database, is to speed up your tests, then there are better ways.

Use FactoryGirl.build as much as possible instead of create. This works as long as the record won't be fetched from the database by your code. This works well for unit tests with well-structured code. (For example, it helps to use Service Objects and unit test them independently.

For tests that actually need to read from the database (as in your Foo.first example call), you can use FactoryGirl.create and use transactional fixtures. This creates a database transaction at the beginning of each test example, and then rolls back the transaction at the end of the example. This can cause problems when you use callbacks in your ActiveRecord models such as after_commit.

If you use after_commit or other callbacks in your models that require the database transaction to close (or you use explicit transactions in your code), I recommend setting up DatabaseCleaner. Here's an example of to configure and use it: https://gist.github.com/RobinDaugherty/9f4e5f782d9fdbe191a23de30ad8b539

Sign up to request clarification or add additional context in comments.

2 Comments

Yes, my motivation is keeping the test suite speedy. I'm using FactoryGirl.build and FactoryGirl.build_stubbed as much as possible, but I was looking for a way to eliminate the database dependency entirely. I don't think transactional fixtures will accomplish what I want either. This might be a case of premature optimization on my part, but I just wanted to make sure it wasn't possible before I start writing tests with database interaction.
I doubt that you will see any substantial increase in speed going from FactoryGirl.build to using stubs. But you will definitely lose quality in your tests, since using a model factory ensures that model behavior is correct. I wouldn't recommend it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.