对于上下文,这个问题之所以出现,是因为我们正在从Rails 5迁移到Rails 6,并且通过新的复制特性引入了读取器/写入器数据库连接。
我们的具体问题是请求规范,着眼于使用事务性fixture。当我们单独运行请求规范文件时,它们通过。当作为多文件传递的一部分运行时(例如在circle CI上使用完整的bundle exec parallel_rspec
传递),它们失败。如果我们关闭事务性fixture,测试运行时间太长,但通过了。
使用byebug
,我们已经插入并确定问题在于我们的测试数据已经被写入到writer DB连接/可以被writer DB连接访问,但是路由尝试使用reader DB连接来读取它,即ActiveRecord::Base.connected_to(role: :reading) { puts Foo.count }
是0,而连接到writing角色的相同代码是非零的。
由此产生的问题似乎相当明显:因为我们使用的是事务性测试/fixture,所以代码永远不会提交到数据库。它只在连接上可用。请求规范从“正确”的数据库中阅读调用(GET请求应该使用reader数据库),但在测试用例中会产生错误。
这似乎是一个相当明显的用例,Rails或rspec * 应该 * 有一个工具来处理,我们只是似乎无法找到相关的文档。
1条答案
按热度按时间s6fujrry1#
您需要告诉测试环境,它应该为这两个连接使用一个连接。有多种方法可以做到这一点:
1.您可以将
test
环境配置为根本不使用副本。有关使用副本和不使用副本的示例,请参阅设置应用程序,然后在database.yml
中重现非副本版本(仅用于测试环境)。1.你可以在你的规范中使用
connected_to
,这样那些测试就会被强制使用你希望它们使用的特定连接。一种方法是使用around
钩子:1.您可以在
rails_helper
中修补ActiveRecord配置,这样它就不会使用副本(但我真的建议使用#1而不是此选项)