Rails 4:如何在集成测试期间从Rails应用程序外部发出请求?
Rails 4: how to make request from outside of Rails app during integration test?
我有一个应用程序需要与外部守护程序 (bitcoind) 进行双向通信。 bitcoind 中的功能允许在新块或感兴趣的交易发生时调用我的应用程序('--walletnotify' 和 '--blocknotify')。为此,我使用 CURL 来请求“http://myapp/walletnotify”等等:
walletnotify = /usr/bin/curl --max-time 60 http://myapp/walletnotify/%s
我正在尝试为此回调行为创建集成测试。不幸的是,当 运行ning 集成测试时,我在守护程序端收到错误,因为它无法执行对“http://myapp/walletnotify”的请求 - 显然 Rails 服务器无法访问(或连接中断?)。当然,测试失败是因为没有调用适当的操作。
我的问题是:如何正确测试这种情况?有什么方法可以在集成测试期间允许对应用程序的直接外部请求?有没有办法确保 Rails 服务器在集成测试期间处于 运行ning 状态?或者我应该在集成测试中听取此类请求,然后将它们代理到应用程序?
2018-06-03 更新:我正在使用 minitest。我正在尝试 运行 的测试在这里:
https://github.com/cryptogopher/token_voting/blob/master/test/integration/token_votes_notify_test.rb
调用后
@rpc.generate(101)
regtest 模式下的 bitcoind 守护程序应生成 101 个块并调用 'blocknotify' 回调。问题是它无法在测试期间向应用程序发送 HTTP 请求。
好的,我解决了这个问题。
看起来 'minitest' 不会启动应用程序服务器,无论您选择哪个 driver。您仍然可以启动自己的 HTTP 服务器来侦听来自外部源的通知并将它们转发给测试的应用程序。
为此,您需要:
require 'webrick'
设置 HTTP 服务器(禁用日志记录以避免混乱):
server = WEBrick::HTTPServer.new(
Port: 3000,
Logger: WEBrick::Log.new("/dev/null"),
AccessLog: []
)
指定如何处理传入的 HTTP 请求。在我的例子中,只有 GET 请求,但重要的是用原始 headers:
转发它们
server.mount_proc '/' do |req, resp|
headers = {}
req.header.each { |k,v| v.each { |a| headers[k] = a } }
resp = get req.path, {}, headers
end
在单独的线程中启动 HTTP 服务器(它阻塞了它所在的线程 运行):
@t = Thread.new {
server.start
}
Minitest.after_run do
@t.kill
@t.join
end
Timeout.timeout(5) do
sleep 0.1 until server.status == :Running
end
我有一个应用程序需要与外部守护程序 (bitcoind) 进行双向通信。 bitcoind 中的功能允许在新块或感兴趣的交易发生时调用我的应用程序('--walletnotify' 和 '--blocknotify')。为此,我使用 CURL 来请求“http://myapp/walletnotify”等等:
walletnotify = /usr/bin/curl --max-time 60 http://myapp/walletnotify/%s
我正在尝试为此回调行为创建集成测试。不幸的是,当 运行ning 集成测试时,我在守护程序端收到错误,因为它无法执行对“http://myapp/walletnotify”的请求 - 显然 Rails 服务器无法访问(或连接中断?)。当然,测试失败是因为没有调用适当的操作。
我的问题是:如何正确测试这种情况?有什么方法可以在集成测试期间允许对应用程序的直接外部请求?有没有办法确保 Rails 服务器在集成测试期间处于 运行ning 状态?或者我应该在集成测试中听取此类请求,然后将它们代理到应用程序?
2018-06-03 更新:我正在使用 minitest。我正在尝试 运行 的测试在这里:
https://github.com/cryptogopher/token_voting/blob/master/test/integration/token_votes_notify_test.rb
调用后
@rpc.generate(101)
regtest 模式下的 bitcoind 守护程序应生成 101 个块并调用 'blocknotify' 回调。问题是它无法在测试期间向应用程序发送 HTTP 请求。
好的,我解决了这个问题。
看起来 'minitest' 不会启动应用程序服务器,无论您选择哪个 driver。您仍然可以启动自己的 HTTP 服务器来侦听来自外部源的通知并将它们转发给测试的应用程序。
为此,您需要:
require 'webrick'
设置 HTTP 服务器(禁用日志记录以避免混乱):
server = WEBrick::HTTPServer.new(
Port: 3000,
Logger: WEBrick::Log.new("/dev/null"),
AccessLog: []
)
指定如何处理传入的 HTTP 请求。在我的例子中,只有 GET 请求,但重要的是用原始 headers:
转发它们server.mount_proc '/' do |req, resp|
headers = {}
req.header.each { |k,v| v.each { |a| headers[k] = a } }
resp = get req.path, {}, headers
end
在单独的线程中启动 HTTP 服务器(它阻塞了它所在的线程 运行):
@t = Thread.new {
server.start
}
Minitest.after_run do
@t.kill
@t.join
end
Timeout.timeout(5) do
sleep 0.1 until server.status == :Running
end