Web API testing library
Mass Spec prevents HTTP::Server
from starting a TCPServer
and use IO::Memory
instead of TCPSocket
for fast testing.
Since Mass Spec works with standard library, it can easily support the frameworks based on HTTP::Server
.
Add this to your application's shard.yml
:
development_dependencies:
mass_spec:
github: c910335/mass-spec
require "spec"
require "mass_spec"
include MassSpec::GlobalDSL
server = HTTP::Server.new do |context|
context.response.content_type = "application/json"
context.response.print(context.request.body.try &.gets_to_end)
end
server.listen
describe "Server" do
it "echoes in json" do
post("/", body: {
"Khassar de templari!" => "From order comes justice!",
"Adun Toridas!" => "Adun hide you",
"Nahda gahla" => nil,
}.to_json)
status_code.should eq(200)
headers.should contain({"Content-Type", ["application/json"]})
body.should eq(%({"Khassar de templari!":"From order comes justice!","Adun Toridas!":"Adun hide you","Nahda gahla":null}))
json_body.should eq({
"Khassar de templari!" => "From order comes justice!",
"Adun Toridas!" => "Adun hide you",
"Nahda gahla" => nil,
})
json_body.should contain({
"Khassar de templari!" => "From order comes justice!",
"Adun Toridas!" => String,
})
json_body.should match({
"Khassar de templari!" => String,
"Adun Toridas!" => "Adun hide you",
"Nahda gahla" => Nil,
})
end
end
Mass Spec supports the following HTTP verbs via HTTP::Client
, and the usage of them is the same as HTTP::Client
.
After a request, you can access these getters.
- response :
HTTP::Client::Response
- status_code :
Int32
- headers :
HTTP::Headers
- body :
String
- json_body :
JSON::Any
- The body parsed asJSON::Any
Besides built-in expectations, Mass Spec also provides contain
and match
for JSON::Any
.
json = JSON.parse(%({"array":[1,2,3],"number":1,"float_number":1.5,"string":"str","null":null,"hash":{"a":1}}))
describe "contain with JSON::Any" do
it "checks whether json contains the values or types" do
json.should contain({
"array" => Array,
"number" => 1,
"hash" => {"a" => Int64},
})
end
end
describe "match with JSON::Any" do
it "checks whether json matches the values or types" do
json.should match({
"array" => [1, 2, 3],
"number" => Int64,
"float_number" => 1.5,
"string" => String,
"null" => nil,
"hash" => Hash,
})
end
end
You can specify headers
that will be applied to every requests.
MassSpec.configure do
headers({"Authorization" => "Bearer some_access_token"})
end
Kemal doesn't run HTTP::Server#listen
when ENV["KEMAL_ENV"]
is "test"
, so you need to set MassSpec.server
manually.
# src/your_app.cr
require "kemal"
get "/hello" do
{hello: "kemal"}.to_json
end
Kemal.run
# spec/spec_helper.cr
ENV["KEMAL_ENV"] = "test"
require "spec"
require "mass_spec"
require "../src/*"
include MassSpec::GlobalDSL
Kemal.run do |config|
MassSpec.server = config.server.not_nil! # set `MassSpec.server` manually
end
# spec/your_app_spec.cr
require "./spec_helper"
describe "GET /hello" do
it "says hello to Kemal" do
get "/hello"
json_body.should eq({"hello" => "kemal"})
end
end
# src/controllers/hello_controller.cr
class HelloController < Amber::Controller::Base
def hello
respond_with { json({"hello" => "amber"}) }
end
end
# config/routes.cr
Amber::Server.configure do
routes :web do
get "/hello", HelloController, :hello
end
end
# spec/spec_helper.cr
ENV["AMBER_ENV"] = "test"
require "spec"
require "mass_spec"
require "../src/*" # not `require "../config/*"`
include MassSpec::GlobalDSL
# spec/controllers/spec_helper.cr
require "../spec_helper"
# spec/controllers/hello_controller_spec.cr
require "./spec_helper"
describe HelloController do
describe "GET #hello" do
it "says hello to Amber" do
get "/hello"
json_body.should eq({"hello" => "amber"})
end
end
end
- Fork it ( https://github.com/c910335/mass-spec/fork )
- Create your feature branch (git checkout -b my-new-feature)
- Commit your changes (git commit -am 'Add some feature')
- Push to the branch (git push origin my-new-feature)
- Create a new Pull Request
- c910335 Tatsiujin Chin - creator, maintainer