如何在RSpec测试中完全避免使用数据库?

时间:2017-02-03 18:13:59

标签: rails-activerecord factory-bot ruby-on-rails-5 rspec3 rspec-mocks

我想使用FactoryGirl来构建模型的内存存根,然后让所有ActiveRecord查询仅针对那些运行。例如:

# 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.

解决方案可能是使用内存数据库。但上述情况是否可能?

1 个答案:

答案 0 :(得分:0)

如果您避开数据库的原因是为了加快测试速度,那么有更好的方法。

尽可能使用FactoryGirl.build代替create。只要您的代码无法从数据库中获取记录,这就可以正常工作。这适用于结构良好的代码的单元测试。 (例如,它有助于使用Service Objects并单独对它们进行单元测试。

对于实际需要从数据库中读取的测试(如在Foo.first示例调用中),您可以使用FactoryGirl.create并使用事务夹具。这将在每个测试示例的开头创建一个数据库事务,然后在示例结尾处回滚事务。当您在ActiveRecord模型中使用回调时,这可能会导致问题,例如after_commit

如果在模型中使用after_commit或其他要求关闭数据库事务的回调(或者在代码中使用显式事务),我建议设置DatabaseCleaner。以下是配置和使用它的示例:https://gist.github.com/RobinDaugherty/9f4e5f782d9fdbe191a23de30ad8b539