gpt4 book ai didi

ruby-on-rails - 如何通过 Rspec 测试 Redis 锁

转载 作者:可可西里 更新时间:2023-11-01 11:15:05 28 4
gpt4 key购买 nike

我们有一个 Lockable 问题,允许通过 Redis 进行锁定

module Lockable
extend ActiveSupport::Concern

def redis_lock(key, options = {})
Redis::Lock.new(
key,
expiration: options[:expiration] || 15,
timeout: options[:timeout] || 0.1
).lock { yield if block_given? }
end
end

我们在 Controller 方法中使用它来确保正确处理并发请求。

def create
redis_lock(<generated_key>, timeout: 15) do
# perform_operation
end

render json: <data>, status: :ok
end

测试此操作时,我想测试是否将正确的 generated_key 发送到 Redis 以启动锁定。

我为 Redis::Lock 设置了一个 expect 但它总是返回 false 大概是因为创建请求是在请求中间而不是在请求结束时发送的。

expect(Redis::Lock).to receive(:create).once

测试结构:

context 'return status ok' do
When do
post :create, params: {
<params>
}
end
Then {
expect(Redis::Lock).to receive(:create).once
response.ok?
}
end
end

由于锁在方法调用结束时被清除,所以我无法在redis中检查 key 作为测试。

This answer建议设置一个与 Lockable 的结构相匹配的假类来模拟相同的行为,但是我该如何为它编写测试呢?我们的方法没有返回任何值来验证。

最佳答案

根据您提供的代码,我相信您只是设置了错误的测试:

expect(Redis::Lock).to receive(:create).once

这需要 Redis::Lock 类接收 create 调用,但您正在 Controller 中调用 create

您在 redis_lock 方法中正在做的是初始化 Redis::Lock实例并调用锁定。在我看来,这就是您应该测试的内容:

expect_any_instance_of(Redis::Lock).to receive(:lock).once

实现看起来像这样:

describe 'Lockable' do
describe '#redis_lock' do
subject { lockable.redis_lock(key, options) }

# you gotta set this
let(:lockable) { xyz }
let(:key) { xyz }
let(:options) { x: 'x', y: 'y' }

it 'calls Redis::Lock.new with correct arguments' do
expect(Redis::Lock).to receive(:new).with(key: key, options: options)
subject
end

it 'calls #lock on the created Redis::Lock instance' do
expect_any_instance_of(Redis::Lock).to receive(:lock).once
subject
end
end
end

关于ruby-on-rails - 如何通过 Rspec 测试 Redis 锁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51764538/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com