带Redis的片状测试

时间:2019-09-19 20:59:46

标签: ruby-on-rails ruby multithreading testing redis

我有一个单元测试,用于在Redis中(在Rails应用程序中)缓存API密钥。

redis通过connection_pool gem设置为全局变量($redis)。所以我做了$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

2 个答案:

答案 0 :(得分:0)

我删除了travel 5.minutes语句和测试似乎现在可以正常工作了,而且没有任何问题。 ?‍♂️

答案 1 :(得分:0)

将其作为答案在此处以获得更多可见性。

travel 5.minutesTime.now和其他相关方法进行存根处理,以将时间增加/减少所需的持续时间。 在测试结束时删除存根。我认为这意味着在整个测试套件执行结束时。这可能是导致片状测试的原因。

travel还提供了一个选项,以提供一个块,然后重设存根。 因此,类似

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

可能是更合适的方法,因为一旦检查了所需的断言,它将删除存根。 更多内容: https://api.rubyonrails.org/v6.0.0/classes/ActiveSupport/Testing/TimeHelpers.html#method-i-travel