使用 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 编写测试的主要内容,如果未能解决你的问题,请参考以下文章

带有视图测试和嵌套资源的 Rspec 和 Rails

devise 和 rspec-rails - 如何在请求类型规范(带有 type: :request 标记的规范)中登录用户?

使用 RSpec & Rails 测试给定布局的渲染

使用 RSpec 测试 Rails 辅助方法时如何在参数哈希中设置值?

在某些 RSpec rails 请求示例中测试 HTTP 状态代码,但在其他示例中测试引发异常

在 Rails 的 rspec 中,我如何编写/编辑我的测试文件,以便特定上下文中的示例以设定的顺序运行?