使用 RSpec 在 Rails 上测试 Ruby 中的 Thrift 代码的最佳方法是什么

What is the best way to test Thrift code in Ruby on Rails using RSpec

我在 Rails 应用程序上有一个 Ruby 使用 Thrift 与客户端通信。 现在我的代码在控制器中,每当客户端在特定路径上调用 POST 时,它就会被重定向到我的控制器,然后我创建一个像这样的 Thrift 传输对象:

transport = Thrift::IOStreamTransport.new request.body, response.stream

然后使用处理器和普通旧 ruby 对象作为处理程序。

但是,我需要测试这个控制器(使用 RSpec)。

我不能只使用客户端代码,因为客户端代码需要服务器运行,而这在测试环境中不可用。

关于如何在 RSpec 中测试 Thrift 代码有什么想法吗?

如果来自 IOStreamTransport 的响应不重要,而只是构建传输并在其上调用某些东西,请考虑模拟传输。


let(:fake_transport) { double("fake_transport") }
before do
  expect(Thrift::IOStreamTransport).to receive(:new).with(request.body, anything).and_return(fake_transport)
  expect(Processor).to receive(:new).with(fake_transport).and_return(true)
end

有些人可能会说这将您绑定到您的实现 - 但您已经很好地将职责封装在测试对象中,因此您应该期望使用它们。

另一种选择是使用类似 webmock 的东西来构建虚假响应。如果你想做的话,这也可以处理集成测试。

因此,深入了解 Thrift 库以及 RSpec 的工作原理,我想出了一个使用自定义 Transport

的解决方法
class TestTransport < Thrift::BaseTransport
  def initialize(delegate)
    @delegate = delegate
    @outbuf = Thrift::Bytes.empty_byte_buffer
  end

  def open?; true end
  def read(sz); @inbuf.read sz end
  def write(buf); @outbuf << Thrift::Bytes.force_binary_encoding(buf) end

  def flush
    @delegate.request.accept = "application/vnd.app.v1+x-thrift-json"
    @delegate.post :handle, @outbuf
    data = @delegate.response.body
    data = Thrift::Bytes.force_binary_encoding(data)
    @inbuf = StringIO.new data
    @outbuf = Thrift::Bytes.empty_byte_buffer
  end
end

这段代码主要是从 Thrift 的 HTTPClientTransport 复制而来的,只是在调用 NetIO 的地方 post 我只是在 Delegate 上调用 post,它只是 RSpec 对象