Ruby Sinatra单元测试-带有JSON主体的post

Ruby Sinatra单元测试-带有JSON主体的post,ruby,unit-testing,sinatra,rack-test,Ruby,Unit Testing,Sinatra,Rack Test,我正在尝试为我使用Sinatra构建的RESTAPI构建一个单元测试。现在我只想测试我的echo函数是否正常工作。Echo使用POST并将从POST返回完全相同的有效负载。我对ruby还是新手,所以如果我没有使用正确的行话,请原谅我 下面是我要测试的代码: post '/echo' do request.body.read end 这是我试图进行的单元测试: ENV['RACK_ENV'] = 'test' require './rest_server' require 'test/uni

我正在尝试为我使用Sinatra构建的RESTAPI构建一个单元测试。现在我只想测试我的echo函数是否正常工作。Echo使用POST并将从POST返回完全相同的有效负载。我对ruby还是新手,所以如果我没有使用正确的行话,请原谅我

下面是我要测试的代码:

post '/echo' do
  request.body.read
end
这是我试图进行的单元测试:

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
如果我尝试在不使用
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'
如果我尝试在
data='hello'
的位置执行此操作,则会得到相同的
未定义的方法'key?'
错误

我尝试过这个建议,但没有成功: 我得到一个错误,说
post
只接受2个参数,而不是3个

总之,我需要能够进行调用,让我正在测试的代码接收调用并返回响应,然后我需要能够读取响应并验证它是原始数据。现在看来,它只是在打电话时被卡住了

谢谢,
Barry

机架测试将在
最后一次响应中返回响应主体。主体
,无需将其保存到变量中。您也没有回显您发送的内容-
数据
在您提供的代码中是JSON,但您将其转换为哈希并发布,因此它与返回的内容不匹配。发送JSON,或者在Sinatra路由中将其转换为JSON(如需更多信息,请参阅)

在Sinatra应用程序中:

require 'json'

post '/echo' do
  # Don't use request.body.read as you're not posting JSON
  params.to_json
end
在测试文件中:

def test_check_methods
  data = '{"dataIn": "hello"}'
  post '/echo', JSON.parse(data)
  assert.last_response.ok?
  assert(last_response.body == data)
end

如果你真的想发布JSON(如果我认为这是一个好主意,如果它很容易转换或已经有数据作为哈希),那么使用<代码>:提供= >“JSON”< /C>作为A,并考虑使用来使测试更容易写(注:这是我写的一个宝石的无耻插件)< /P> < P>我做了一点类似的事情,它可能会帮助您:

申请职位定义:

post '/' do
    data = JSON.parse request.body.read.to_s
    "Hello !\n#{data.to_s}"
end
.to_是必需的,否则转换将不完全相同:-/

然后在测试文件上:

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
class RootPostTest1,
“signedReqID”=>“plop”,
“证书”=>“迈科特”
}
发布“/”,data.to_json,“内容类型”=>“应用程序/json”
断言最后的响应。确定吗?
body_spected=“Hello!\n#{JSON.parse(data.to_JSON.to_s}”
断言等于最后一个响应。主体,主体
结束
结束

希望它对您有所帮助。

我认为您应该为此进行集成测试,而不是单元测试。单元测试用于测试类,而不是测试请求。也许这个问题会有帮助?你试过仅仅发布数据结构吗<代码>发布“echo”,{“dataIn”=>“hello”}
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