Rspec - Kiểm tra JSON schema dùng rspec matcher
TIL
594
Rspec
5
RubyOnRails
40
White

Dang Tung Lam viết ngày 26/06/2016

Rspec - Kiểm tra JSON schema dùng rspec matcher

Nay mình có viết TDD để check Repsonse Body của API (ở JSON format) có khớp với mẫu định sẵn hay không. Thông thường thì mình sẽ dùng 1 vài thủ thuật để check response body có đủ các key mà mình expect hay không, qua bài viết này mình tìm thấy 1 cách khác để kiểm tra: check schema của JSON.

JSON schema là 1 mẫu biểu diễn cấu trúc dữ liệu của chuỗi JSON. Có thể coi là 1 đặc tả kỹ thuật của JSON giúp cho việc tạo documentation, validation với JSON data dễ dàng hơn [xem rõ hơn ở đây]

Tích hợp vào rspec

Ứng dụng của mình đang dùng là Rails (4).

gem json-schema là 1 JSON schema validator cho ruby. Add nó vào Gemfile:

group :test do
  gem "json-schema"
end

Định nghĩa Rspec matcher ở spec/json_helper.rb.
Đặt tên matcher là match_response_schema

require 'rspec/expectations'

# matcher này nhận biến vào là tên schema
RSpec::Matchers.define :match_response_schema do |schema|
  match do |response|
    # Định nghĩa đến đường dẫn chứa schema
    schema_directory = "#{Dir.pwd}/spec/support/api/schemas"
    schema_path = "#{schema_directory}/#{schema}.json"

    # JSON::Validator.validate! được cung cấp bởi gem json-schema
    # nó so sánh body của response có khớp với schema đã định nghĩa hay không
    # truyền strict: true để đảm bảo hàm sẽ fail khi response body không matching với schema
    JSON::Validator.validate!(schema_path, response.body, strict: true)
  end
end

Các bạn có thể xem thêm cách viết matcher ở đây nhé

Viết JSON Schema.

Giả sử đây là dữ liệu mình mong muốn nhận được:

{
  "domain": {
    "name": "aekt.net",
    "is_verified": true,
    "dkim": {
      "domain": "aekt.net",
      "is_verified": true,
      "selector": "default",
      "txt_record": "v=DKIM1;t=s;p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCq5sDfCre1WJlaDnokb1rPaXvFYujQQLt0P8B/Nq6D5kKGW5WvusTUD6KrQSylmPOc436yKPGmMPVkDEuxLMuRyssQ//Czq+B7Cp1QDA2yhIvhdIMBZC/iwWwNkTB56ZGIouEI2NlV3vmxzncRHcVwbO8ore89YGsP2k7vw0OzTwIDAQAB"
    }
  }
}

Mình sẽ tạo 1 file chứa JSON schema theo đúng đường dẫnschema_path ở trên, đặt tên schema này là domain:

spec/support/api/schemas/domain.json:

{
    "type": "object",
    "required": [
        "domain"
    ],
    "properties": {
        "domain" : {
            "type" : "object",
            "required" : [
                "name",
                "is_verified"
            ],
            "properties" : {
                "name" : { 
                    "type" : "string" 
                  },
                "is_verified" : {
                    "type" : "boolean"
                 },
                "dkim" : {
                    "type" : "object"
                 }
            }
        }
    }
}

Nếu nhìn theo kiểu trên các bạn chưa hình dung ra các viết JSON schema thì mình có thể hướng dẫn ;)

Các giá trị của type xem ở đây

Tiếp theo mình sẽ include json_helper vào spec test:

spec/api/domain_spec.rb:

require 'rails_helper'
require 'json_helper'

RSpec.describe 'Domain API' do
    let(:domain) {
        'aekt.net'
    }

    describe 'response' do
      it 'code should be 200' do
        get "/#{domain}", {}
        expect(response).to have_http_status(200)
      end

      it 'body should match the schema' do
        get "/#{domain}", {}
        expect(response).to match_response_schema("domain")
      end
    end
  end

end

Giờ có thể chạy bundle exec rspec để kiểm tra.

lamdt 26-06-2016

Bình luận


White
{{ comment.user.name }}
Bỏ hay Hay
{{comment.like_count}}
Male avatar
{{ comment_error }}
Hủy
   

Hiển thị thử

Chỉnh sửa

White

Dang Tung Lam

2 bài viết.
0 người follow
Kipalog
{{userFollowed ? 'Following' : 'Follow'}}
Cùng một tác giả
White
2 1
Font chữ để hiển thị password spam thêm bài nữa để lấy feed url ;( Tuần vừa qua công ty mình gặp hiện tượng: Khách hàng báo không đăng nhập được...
Dang Tung Lam viết 2 năm trước
2 1
Bài viết liên quan
White
1 5
Chào mọi người, với những bạn sử dụng Vagrant (hoặc các Linux Server) để làm môi trường phát triển thì khi run rspec request test (option :js = tru...
Dinh Hoang Hiep viết 3 năm trước
1 5
White
0 0
How to assert table html in page with rspec/capybara Nếu ai đã từng viết cucumber thì mình nghĩ sẽ có nhiều người sử dụng đến thư viện spreewald v...
hoasung01 viết hơn 1 năm trước
0 0
White
0 1
TL;DR Cần thu thập thông tin của các đối tượng search theo keyword trên google = Viết script trên frameword (Link) để làm tự động, thay vì làm bằn...
ManhDV viết hơn 1 năm trước
0 1
{{like_count}}

kipalog

{{ comment_count }}

bình luận

{{liked ? "Đã kipalog" : "Kipalog"}}


White
{{userFollowed ? 'Following' : 'Follow'}}
2 bài viết.
0 người follow

 Đầu mục bài viết

Vẫn còn nữa! x

Kipalog vẫn còn rất nhiều bài viết hay và chủ đề thú vị chờ bạn khám phá!