ruby-on-rails - 使用 Redis 进行片状测试

标签 ruby-on-rails ruby multithreading testing redis

我有一个用于在 redis 中缓存 API key 的单元测试(在 Rails 应用程序中)。

redis 被设置为全局变量 ($redis),带有 connection_pool gem .所以我执行 $redis.with do |redis| 来实际获得 redis 连接。

问题是,我的测试非常不稳定。它有两个断言:一个用于测试获取预期值,另一个用于测试该值是否已缓存(10 分钟)。

jwt = JWT.encode payload, private_key, "RS256"
assert_equal jwt, Foo.app_token
travel 5.minutes
assert_equal jwt, Foo.app_token

我不明白为什么测试如此不稳定。它可能每 3-5 次运行就会失败。任何帮助将不胜感激。我从来没有真正在连接池中使用过 Redis,所以很可能会做一些基本的错误。

方法的实现:

def app_token
  find_app_token || create_app_token
end

private

def find_app_token
  $redis.with { |redis| redis.get APP_KEY }
end

def create_app_token
  payload = # some payload
  JWT.encode(payload, private_key, "RS256").tap do |jwt|
     $redis.with do |redis|
       redis.set APP_KEY, jwt
       redis.expireat APP_KEY, payload[:exp]
     end
  end
end

最佳答案

将其作为答案放在这里以提高知名度。

travel 5.minutesTime.now 和其他相关方法进行 stub ,以按所需持续时间增加/减少时间。 在测试结束时 移除 stub 。我认为他们的意思是在整个测试套件执行结束时。这可能是片状测试的可能原因。

travel 还提供了一个选项来提供一个 block ,之后 stub 将被重置。 因此,像

travel 5.minutes do
 assert_equal jwt, Foo.app_token
end

可能是一种更合适的方法,因为它会在检查所需的断言后立即删除 stub 。 更多信息: https://api.rubyonrails.org/v6.0.0/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel

关于ruby-on-rails - 使用 Redis 进行片状测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58018867/

相关文章:

ruby-on-rails - Rails 预加载问题 Find( :all, :include => [:model])

ruby-on-rails - FactoryBot 可以在创建模型后生成工厂吗?

ruby-on-rails - Rails 概括了使用模型的方法

java - 为多个应用程序修复 Windows 7 环境变量中的 'PATH'

c# - 使用 DateTime.Now.Ticks 生成唯一的数字 ID

javascript - 在 Rails 上加载 WebAssembly 二进制文件

html - 用 Mechanize 解析html页面以接收适当的数组

html - 如何生成与 Rails 应用程序的 html 文件匹配的 Assets ?

c++ - Qt/C++ 将 worker 的父级更改为 qthread 失败

c++ - 如何让每个线程传递另一个参数?