use*_*753 4 ruby unit-testing sinatra rack-test
我正在尝试为我使用 Sinatra 构建的 REST API 构建单元测试。现在我只想测试我的回声功能是否正常工作。Echo 使用 POST 并将从帖子中返回完全相同的有效负载。我对 ruby 还是个新手,所以如果我不使用正确的术语,请原谅我。
这是我要测试的代码:
post '/echo' do
request.body.read
end
Run Code Online (Sandbox Code Playgroud)
这是我正在尝试进行的单元测试:
ENV['RACK_ENV'] = 'test'
require './rest_server'
require 'test/unit'
require 'rack/test'
require 'json'
class RestServer < Test::Unit::TestCase
def app
Sinatra::Application
end
def test_check_methods
data = '{"dataIn": "hello"}'
response = post '/echo', JSON.parse(data)
assert.last_response.ok?
assert(response.body == data)
end
end
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,这里是错误:
NoMethodError: undefined method `dataIn' for Sinatra::Application:Class
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1285:in `block in compile!'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1285:in `each_pair'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1285:in `compile!'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1267:in `route'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1256:in `post'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1688:in `block (2 levels) in delegate'
/Users/barrywilliams/RubymineProjects/project/rest_server_test.rb:20:in `test_check_methods'
Run Code Online (Sandbox Code Playgroud)
如果我尝试在没有 的情况下进行JSON.parse,我会得到
NoMethodError: undefined method `key?' for "{\"dataIn\": \"hello\"}":String
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1265:in `route'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1256:in `post'
/Users/barrywilliams/.rvm/gems/ruby-1.9.3-p448/gems/sinatra-1.3.4/lib/sinatra/base.rb:1688:in `block (2 levels) in delegate'
/Users/barrywilliams/RubymineProjects/project/rest_server_test.rb:20:in `test_check_methods'
Run Code Online (Sandbox Code Playgroud)
如果我尝试在 where 中执行此操作data = 'hello',则会收到相同的undefined method 'key?'错误
我试过这个建议,但没有成功:http :
//softwareblog.morlok.net/2010/12/18/testing-post-with-racktest/
我收到一个错误,说post只需要 2 个参数,而不是 3 个。
所以,总而言之,我需要能够拨打电话,让我正在测试的代码接收电话并返回响应,然后我需要能够读取该响应并验证它是原始数据。现在看起来它只是在打电话。
谢谢,巴里
小智 8
我做了一个有点类似的事情,它可能对你有帮助:
申请职位定义:
post '/' do
data = JSON.parse request.body.read.to_s
"Hello !\n#{data.to_s}"
end
Run Code Online (Sandbox Code Playgroud)
.to_s 是必要的,否则转换将不会完全相同:-/
然后在测试文件上:
class RootPostTest < Test::Unit::TestCase
include Rack::Test::Methods
def app
Sinatra::Application
end
def test_return_the_parameters
data = {
'reqID' => 1,
'signedReqID' => "plop",
'cert' => "mycert"
}
post '/', data.to_json, "CONTENT_TYPE" => "application/json"
assert last_response.ok?
body_espected = "Hello !\n#{JSON.parse(data.to_json).to_s}"
assert_equal last_response.body, body_espected
end
end
Run Code Online (Sandbox Code Playgroud)
希望对你有帮助。
Rack Test 将为您返回 中的响应正文last_response.body,无需将其保存到变量中。您也不会回显您发送的内容 -data在您给出的代码中是 JSON,但您将其转换为哈希并发布,因此它不会与返回的内容匹配。发送 JSON,或者如果您愿意的话,可以在 Sinatra 路由中将其转换为 JSON(有关更多信息,请参阅/sf/answers/849715541/ )。
在 Sinatra 应用程序中:
require 'json'
post '/echo' do
# Don't use request.body.read as you're not posting JSON
params.to_json
end
Run Code Online (Sandbox Code Playgroud)
并在测试文件中:
def test_check_methods
data = '{"dataIn": "hello"}'
post '/echo', JSON.parse(data)
assert.last_response.ok?
assert(last_response.body == data)
end
Run Code Online (Sandbox Code Playgroud)
如果您最终想要发布 JSON(我认为如果它很容易转换或已经将数据作为哈希值,这通常不是一个好主意),那么将其用作路由的条件:provides => "json",并考虑使用Rack::Test: :接受,让编写测试的生活变得更轻松(注意:这是我写的一个宝石的无耻插件;)