【问题标题】:How to test a JSON REST API如何测试 JSON REST API
【发布时间】:2012-12-06 23:21:36
【问题描述】:

我是 ruby​​ 的新手(使用 ruby​​ 的第一天),所以请原谅任何新手问题和缺乏理解。

我正在尝试验证对 http 标注的响应。

例如,假设端点如下:

https://applicationname-api-sbox02.herokuapp.com 

而且,我正在尝试通过发送如下获取请求来验证用户身份:

get_response = RestClient.get( "https://applicationname-api-sbox02.herokuapp.com/api/v1/users", 
                    {
                        "Content-Type" => "application/json",
                        "Authorization" => "token 4d012314b7e46008f215cdb7d120cdd7",
                        "Manufacturer-Token" => "8d0693ccfe65104600e2555d5af34213"
                    }
                ) 

现在,我想验证响应并执行以下操作: - 解析响应以确保它是有效的 JSON - 进行一些验证并验证 JSON 是否具有正确的数据(例如验证 id == 4) - 如果遇到错误,使用 'raise' 方法引发异常。

在我第一次微弱的尝试中,我尝试了以下方法:

puts get_response.body
if get_response.code == 200
puts "********* Get current user successful"
else
puts "Get current user failed!!"
end 

现在,这返回了获取当前用户成功,但我如何真正解析 json,验证正确的 id,并在发生错误时引发异常?

【问题讨论】:

标签: ruby


【解决方案1】:

编写测试而不是引发异常。

一种直接的方法,使用标准库中的 json 解析器和单元测试框架:

require 'minitest/autorun'
require 'rest_client'
require 'json'

class APITest < MiniTest::Unit::TestCase
  def setup
    response = RestClient.get("https://applicationname-api-sbox02.herokuapp.com/api/v1/users", 
      {
         "Content-Type" => "application/json",
         "Authorization" => "token 4d012314b7e46008f215cdb7d120cdd7",
         "Manufacturer-Token" => "8d0693ccfe65104600e2555d5af34213"
      }
    ) 
    @data = JSON.parse response.body
  end

  def test_id_correct
    assert_equal 4, @data['id']
  end
end

使用ruby $filename执行

JSON.parse 将 JSON 字符串解析为 ruby​​ hash

Getting started with minitest

如果您使用的是 ruby​​ 1.8,则需要安装 json gem 并安装 minitest gem,或切换到较旧的 testunit API。如果选择后者,则需要更改require 'minitest/autorun' -> require 'test/unit'MiniTest::Unit::TestCase -> Test::Unit::TestCase

【讨论】:

  • 嗨@ireddick,感谢您的帮助。我试过你的例子,但得到了错误:未初始化的常量 Minitest
  • 我正在运行 1.9.3p327 (2012-11-10) [i386-mingw321]
  • @Dman100 - “未初始化的常量 Minitest”表示您输入错误的 MiniTest
  • 测试确实运行了...谢谢。却得到了意想不到的结果。它显示预期结果是“id”而不是 id 值,即 4。
  • 谢谢@ireddick!有没有等价的断言不等于?
【解决方案2】:

我参加聚会有点晚了,但我最近为此共同创建了一个名为 Airborne 的 rspec 驱动框架。看看吧:https://github.com/brooklynDev/airborne

【讨论】:

    【解决方案3】:

    这是我们规范中的一个示例,因此您可以了解我们如何测试 json api:

    it 'returns charge' do
      get "/charges/#{charge.id}", '', headers
    
      expect(response.status).to eq(200)
      expect(response).to match_response_schema(:charge)
      expect(response).to match_json(<<-JSON)
      {
        "id":"{id}",
        "email": "{email}",
        "ip": "127.0.0.1",
        "amount": 10500,
        "state": "captured",
        "captured_amount": 10500,
      }
      JSON
    end
    

    让我们仔细看看

    1. match_response_schema(:charge)

    这个匹配器检查我们在响应中得到的 json 通常是有效的。我们为此使用json-schema(json 模式验证器)。来自 Thoughtbot 的人在这篇博文中有 a detailed guide 如何使用 json 模式验证器并创建自己的匹配器。

    Understanding JSON Schema 是我获得很多关于如何为 JSON 文档创建模式的有用信息的地方。

    1. match_json

    这是我们自己的匹配器,我们最近发布了match_json gem。使用它,您可以测试 json 的结构和值。以下是此匹配器的两个重要功能:

    • 如果您不知道确切的值,可以使用 {id}、{uuid} {date_time} 等模式。我们有预定义的模式,但您也可以添加自己的模式。
    • 您会收到明确的失败消息,例如您的 json 有什么问题在“ > 数组”中找不到“5”:[1,2,3]

    【讨论】:

      【解决方案4】:

      可以使用 json gem 解析 json:http://flori.github.com/json/

      解析后的 json 是通过 key/value 访问的,就像在 javascript 中一样。您可以轻松验证这些值并有条件地引发错误。

      引发错误是这样完成的:

      raise "the ID was #{id} instead of 4"
      

      编写单元测试可以使用 Test::Unit - http://www.ruby-doc.org/stdlib-1.9.3/libdoc/test/unit/rdoc/Test/Unit.html

      【讨论】:

        猜你喜欢
        • 2018-10-21
        • 1970-01-01
        • 2018-08-30
        • 1970-01-01
        • 1970-01-01
        • 2023-02-23
        • 2019-08-06
        • 2021-06-04
        • 2014-04-28
        相关资源
        最近更新 更多