13

我有一个包含 RailsActionController::Live模块的控制器。我正在显示一个日志文件的内容,该文件正在使用FileTailgem 读取,并使用SSEfromActionController::Live像这样:

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

我想live使用Rspec. 这是我目前拥有的:

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?

有没有办法让这个工作?也许有一种特定的方法必须进行测试,但在任何地方都找不到。

4

1 回答 1

1

您的应用程序中可能有两个问题会阻止您测试代码。

1)您正在使用不包含修复程序的旧版本 rails(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?将有所帮助)。

在轨道 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
于 2019-02-23T12:59:19.043 回答