测试一个包含 ActionController::Live 的控制器
Posted
技术标签:
【中文标题】测试一个包含 ActionController::Live 的控制器【英文标题】:Testing a controller which includes ActionController::Live 【发布时间】:2017-02-16 21:25:27 【问题描述】:我有一个包含 Rails ActionController::Live
模块的控制器。我正在显示使用FileTail
gem 读取的日志文件的内容,并使用ActionController::Live
中的SSE
,如下所示:
class LogsController < ApplicationController
include ActionController::Live
def live
response.headers['Content-Type'] = 'text/event-stream'
sse = SSE.new(response.stream, event: 'queries')
File.open(logfile_location) do |log|
log.extend(File::Tail)
log.interval = 1
log.backward(10)
log.tail |line| sse.write line
end
rescue => e
Rails.logger.info "Error Message:: #e.message"
ensure
sse.close
end
end
我想使用Rspec
测试live
操作。这是我目前拥有的:
before get :live
it expect(response.headers['Content-Type']).to eq("text/event-stream")
after response.stream.close unless response.stream.closed?
如果我没有与after
对应的行,则规范通过但它只是继续侦听并且连接永远不会关闭,因此规范永远不会完成,您必须手动终止它们。
如果我有 after
行,它有时会通过,但大多数时候它会抛出异常,并且规范失败。
fatal:
No live threads left. Deadlock?
有什么方法可以让我完成这项工作吗?也许有一种特定的方法必须进行测试,但在任何地方都找不到。
【问题讨论】:
根据文档,请求似乎被移到了一个单独的线程(主线程之外),这意味着您可能想要遵循这样的内容:***.com/a/27383737/3109182 【参考方案1】:您的应用程序中可能有两个问题会阻止您测试代码。
1) 您正在使用旧版本的 rails 不包含 this fix(rails 5+ 包含它)
2) 显然,当您的代码在没有退出点的情况下运行时,您正在使用File::Tail
。我的意思是:
File.open(logfile_location) do |log|
log.extend(File::Tail)
log.interval = 1
log.backward(10)
log.tail |line| sse.write line
end
永远运行。
因此,您只需要存根 File::Tail
部分,该部分负责永久运行代码或相应地修改您的代码(log.return_if_eof = Rails.env.test?
会有所帮助)。
在 Rails 5.2.2 上测试。此代码有效:
describe "#live" do
subject process :live, method: :get
its(:body) is_expected.to include(file_content) # file_content is content of your file
its(:body) is_expected.to include('event: queries')
its(:headers) is_expected.to match(hash_including('Content-Type' => 'text/event-stream'))
end
【讨论】:
以上是关于测试一个包含 ActionController::Live 的控制器的主要内容,如果未能解决你的问题,请参考以下文章
ActionController::UnknownFormat (ActionController::UnknownFormat): 销毁
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):将 JSON 参数发布到
ActionController::TestCase 模拟 PayPal 购买
Rails 5 ActionController::InvalidAuthenticityToken 错误
设计中的 ActionController::UrlGenerationError::Registrations#create