Ruby on rails 如何测试Sidekiq工作人员是否向外部API发送了正确的数据?

Ruby on rails 如何测试Sidekiq工作人员是否向外部API发送了正确的数据?,ruby-on-rails,unit-testing,rspec,faraday,rspec-mocks,Ruby On Rails,Unit Testing,Rspec,Faraday,Rspec Mocks,我有一个Sidekiq工作人员,他接触到一个外部API以获取一些数据。我正在尝试编写测试,以确保此worker的设计和功能正确。工作人员获取本地模型实例并检查模型上的两个字段。如果其中一个字段为nil,则会将另一个字段发送到远程API 以下是工人代码: class TokenizeAndVectorizeWorker 包括Sidekiq::Worker sidekiq_选项队列:“标记器_向量器”,重试:true,回溯:true def执行(物品编号) article=article.find(

我有一个Sidekiq工作人员,他接触到一个外部API以获取一些数据。我正在尝试编写测试,以确保此worker的设计和功能正确。工作人员获取本地模型实例并检查模型上的两个字段。如果其中一个字段为
nil
,则会将另一个字段发送到远程API

以下是工人代码:

class TokenizeAndVectorizeWorker
包括Sidekiq::Worker
sidekiq_选项队列:“标记器_向量器”,重试:true,回溯:true
def执行(物品编号)
article=article.find(article\u id)
tokenizer\u url=ENV['tokenizer\u url']
如果article.content.nil?
发送内容=article.abstract
其他的
发送内容=article.content
结束
#配置法拉第
conn=Faraday.new(标记器url)do | c|
c、 使用法拉第::响应::RaiseError
c、 标题['Content-Type']='application/x-www-form-urlencoded'
结束
#从标记器获取响应
resp=conn.post'/tokenize',“content={URI.encode(send_content)}”
#响应的主体包含标记化和向量化文章内容的JSON
article.token_vector=各自主体
第1条保存
结束
结束
我想编写一个测试,以确保如果文章内容为零,那么文章摘要就是要发送进行编码的内容

我的假设是,这样做的“正确”方式是用法拉第模拟响应,这样我就可以期待对特定输入的特定响应。通过创建一篇内容为
nil
的文章和一篇摘要
x
,我可以模拟向远程API发送
x
的响应,并模拟向远程API发送
nil
的响应。我还可以创建一篇文章,将
x
作为摘要,将
z
作为
z
的内容和模拟响应

我写了一个测试,通常是在嘲笑法拉第:

it“应该在摄取时获取令牌向量”do
#不要等待异步sidekiq作业
Sidekiq::Testing.inline!
#stub Faraday在没有提出真正要求的情况下归还东西
允许(Faraday::Connection.)的任何实例接收(:post.)并返回(
双重(“响应”,状态:200,正文:“一些数据”)
)
#创建一个属性以手动摄取
属性={
数据源:@data\u source,
标题:Faker::Book.title,
url:Faker::Internet.url,
内容:Faker::Lorem.段落(编号:5).连接(“
”), 摘要:Faker::Book.genre, 发布日期:DateTime.now, 创建时间:DateTime.now } #从属性中摄取一篇文章 状态=物品摄取(属性) #摄取大致在提交给客户的同时发生 #所以我们需要根据id重新获取文章,因为 #它将获得保存到数据库的向量 @token\u vector\u article=article.find(状态[1].id) #我们应该把“一些数据”保存为记号向量 expect(@token\u vector\u article.token\u vector)。not\u to eq(nil) expect(@token\u vector\u article.token\u vector)。用于均衡(“某些数据”) 结束
但这使得法拉第100%的使用都受到了
:post
的嘲弄。在我的特殊情况下,我根本不知道如何用特定的身体来模拟
:post
的响应

也有可能是我的测试完全错误了。我可以改为测试我们是否发送了正确的内容(测试应该检查法拉第发送的内容),而完全忽略正确的响应

测试此工作人员是否做了正确的事情(发送内容,或者如果内容为零则发送摘要)的正确方法是什么?它是为了测试发送的内容,还是测试我们从中得到的反映发送的内容

如果我应该测试返回的内容是发送内容的反映,那么如何根据发送给法拉第的内容的价值模拟法拉第的不同响应/

**后面添加的注释**

我做了一些进一步的挖掘,然后想,好吧,让我测试一下我是否发送了我期望的请求,以及我是否正确处理了响应。所以,我尝试使用webmock

it“应该在内容不是nil时获取文章内容的令牌向量”do
需要“webmock/rspec”
#不要等待异步sidekiq作业
Sidekiq::Testing.inline!
请求_url=“#{ENV['TOKENIZER_url']}/tokenize”
#webmock是预期的请求和响应
存根=存根\请求(:post,请求\ url)
.with(正文:'content=y')
.to_返回(正文:“y”)
#创建一个属性以手动摄取
属性={
数据源:@data\u source,
标题:Faker::Book.title,
url:Faker::Internet.url,
内容:“y”,
摘要:Faker::Book.genre,
发布日期:DateTime.now,
创建时间:DateTime.now
}
#从属性中摄取一篇文章
状态=物品摄取(属性)
#摄取大致在提交给客户的同时发生
#所以我们需要根据id重新获取文章,因为
#它将获得保存到数据库的向量
@token\u vector\u article=article.find(状态[1].id)
#我们应该发送一个content=y的请求
期望(存根)。已被请求
#我们应该把“y”保存为记号向量
expect(@token\u vector\u article.token\u vector)。not\u to eq(nil)
expect(@token\u vector\u article.token\u vector).到等式(“y”)
结束
但我认为webmock在sidekiq的工作中并没有受到重视,因为我知道:

1) Article tokenization and vectorization should fetch token vector for article content when content is not nil
     Failure/Error: expect(stub).to have_been_requested

       The request POST https://zzzzz/tokenize with body "content=y" was expected to execute 1 time but it executed 0 times

       The following requests were made:

       No requests were made.
       ============================================================
如果我尝试在任何其他位置(例如,在文件开头)包含
webmock/rspec
,随机事件就会开始爆炸。例如,如果此等级库文件开头有以下行:

require'spec\u helper'
root@c18df30d6d22:/usr/src/app# bundle exec rspec spec/models/article_spec.rb:174
database: test
Run options: include {:locations=>{"./spec/models/article_spec.rb"=>[174]}}
There was an error creating the elasticsearch index for Article: #<NameError: uninitialized constant Faraday::Error::ConnectionFailed>
There was an error removing the elasticsearch index for Article: #<NameError: uninitialized constant Faraday::Error::ConnectionFailed>