使用 RSpec 为带有 Rails 的 Redis 编写测试
Posted
技术标签:
【中文标题】使用 RSpec 为带有 Rails 的 Redis 编写测试【英文标题】:Writing tests with RSpec for Redis with Rails 【发布时间】:2012-05-17 02:30:59 【问题描述】:我有一个将数据缓存在 redis 中的模型类。我第一次在模型上调用方法时,它会计算 JSON/Hash 值并将其存储在 Redis 中。在某些情况下,我会“刷新”该数据,并在下一次调用时重新计算。
这里的代码 sn-p 类似于我用来在 Redis 中存储数据的代码:
def cache_data
self.data_values = data_to_cache
REDIS.set(redis_key,ActiveSupport::JSON.encode(self.data_values))
REDIS.get(redis_key)
end
def data_to_cache
# generate a hash of values to return
end
我应该如何对这段代码进行单元测试?我使用 RSpec 和 Capybara。如果有帮助,我还会使用 Cucumber 和 Capabara 进行集成测试。
【问题讨论】:
【参考方案1】:我喜欢在测试运行时运行 redis。 Redis,不像例如postgres,速度非常快,并且不会显着减慢测试运行时间。
只要确保在 before(:each)
块中调用 REDIS.flush
,或相应的黄瓜钩子即可。
您可以独立于 redis 测试 data_to_cache
,但除非您完全信任您正在使用的 redis 驱动程序及其提供的合约,否则实际测试 cache_data
(以及相应的缓存获取方法)会更安全。这还允许您切换到不同的 redis 驱动程序(或不同的快速 KV 存储),而无需大规模重写您的测试。
【讨论】:
我相信现在是REDIS.flushdb
【参考方案2】:
首先在 spec_helper.rb 中添加以下代码,这样即使未安装 redis 服务器,您也可以确保测试将在任何机器上运行(确保在测试范围下添加到 gemfile mock_redis:
redis_instance = MockRedis.new
Redis.stub(:new).returns(redis_instance)
Redis::Store.stub(:new).returns(redis_instance)
之后我会测试:
-
写入 REDIS 的数据是预期数据
一系列cache_data、flush_data、cache_data调用data_to_cache两次
【讨论】:
因此,您建议让 redis 运行并实际测试数据与 redis 的交互。这依赖于在运行测试时运行 redis(我一般不反对)。但它添加了一个依赖项,我可以看到有些人可能会建议使用存根处理。 您可能想要添加到此答案顶部的一件非常有帮助的事情是:将gem 'mock_redis'
添加到您的 Gemfile 并将这一行添加到您的 spec_helper 以及 require 'mock_redis'
我有“Redis:Class (NoMethodError) 的未定义方法‘存根’”。 :(
@TiSir - 尝试调用 .stub(:new).and_return(redis_instance)
。
我认为这是模拟redis的一个糟糕的选择,它超级快。更好的选择是启动一个测试 redis 服务器并使用它。我创建了一个可以促进这一点的 gem:rubygems.org/gems/redis_test以上是关于使用 RSpec 为带有 Rails 的 Redis 编写测试的主要内容,如果未能解决你的问题,请参考以下文章
devise 和 rspec-rails - 如何在请求类型规范(带有 type: :request 标记的规范)中登录用户?
使用 RSpec 测试 Rails 辅助方法时如何在参数哈希中设置值?