In the last episode we saw how to create our Gem and its structure. In today's episode we will test everything we did.
Rspec
We have a
rspec
folder where all our tests are located.
bundle exec rspec
We got an error because we need to fix our gemspec file.
The validation error was '"FIXME" or "TODO" is not a description
Let's fix that!
Now if we run rspec, it should be fine.
bundle exec rspec
From the last episode, we forgot to move the version file inside formulae_ruby. Let's move that.
One test failed. Let's remove it That was just to see if it was working.
require 'spec_helper'
RSpec.describe FormulaeRuby do
it 'has a version number' do
expect(FormulaeRuby::VERSION).not_to be nil
end
it 'does something useful' do
expect(false).to eq(true)
end
end
Resources tests
Before starting our tests, let's add
json
and
byebug
in our spec helper. We
might want to use it later, especially JSON.
vim spec/spec_helper.rb
require 'byebug'
require 'json'
We need to organize our tests. Let's create a folder for our resources tests.
mkdir spec/resources
And we will create a
form_spec
file:
vim spec/resources/form_spec.rb
For our test, we will pass some JSON to our Form and wel check if the form responds to specific methods, our attributes.
require 'spec_helper'
RSpec.describe FormulaeRuby::Form do
let(:json) do
JSON.parse({
id: '1',
application: {
id: '1'
},
sections: [
],
questions: [
]
}.to_json)
end
let(:form) { FormulaeRuby::Form.new(json) }
describe 'fields' do
it { expect(form).to respond_to(:id) }
it { expect(form).to respond_to(:application_id) }
it { expect(form).to respond_to(:questions) }
it { expect(form).to respond_to(:sections) }
end
end
Let's make tests to our Sections:
vim spec/resources/section_spec.rb
We will pass some JSON to our Section and check if the model responds to the correct keys.
require 'spec_helper'
RSpec.describe FormulaeRuby::Section do
let(:json) do
JSON.parse({
id: 1,
form_id: 1,
name: 'name',
order: 1,
content: 'content'
}.to_json)
end
let(:section) { FormulaeRuby::Section.new(json) }
describe 'fields' do
it { expect(section).to respond_to(:id) }
it { expect(section).to respond_to(:form_id) }
it { expect(section).to respond_to(:name) }
it { expect(section).to respond_to(:order) }
it { expect(section).to respond_to(:content) }
end
end
Let's do the same thing to our Questions:
vim spec/resources/question_spec.rb
We will check if the keys are correct.
require 'spec_helper'
RSpec.describe FormulaeRuby::Question do
let(:json) do
JSON.parse({
id: '1',
key: 'key',
label: 'label',
order: 1,
content: 'content'
}.to_json)
end
let(:question) { FormulaeRuby::Question.new(json) }
describe 'fields' do
it { expect(question).to respond_to(:id) }
it { expect(question).to respond_to(:key) }
it { expect(question).to respond_to(:label) }
it { expect(question).to respond_to(:order) }
it { expect(question).to respond_to(:content) }
end
end
This covers test for our resources. Let's work with the client tests.
Client tests
For the moment, we just have one client: the FormClient. This client has two methods: all and find. Each of these methods make HTTP requests to our API and if we don't have our API running locally or remotely our tests will fail.
We shouldn't rely on our API to make tests. Additionally, our tests make HTTP requests. It can make our API slow, especially if your API has a rate limit.
We will use
webmock
and
vcr
.
Let's add these in our gemspec:
vim formulae_ruby.gemspec
spec.add_development_dependency 'vcr'
spec.add_development_dependency 'webmock'
Let's do a bundle install, and install these gems.
bundle install
And change our
spec_helper
:
VCR.configure do |c|
c.cassette_library_dir = "test/fixtures"
c.hook_into :webmock
end
As we are using webmock, it will not make a real HTTP request. It intercepts all the requests we made, and then we can return the result of the request. The return of the request will be generated by VCR. We will have a cassette or a fixture file that will be the result of our HTTP request.
The first time, VCR will download the JSON and store it in the file. After the
first time, all requests will check the fixture file. In our case, the fixture
files will be located in
test/fixtures
.
Let's do our first test for our FormClient.
mkdir spec/clients
vim spec/clients/form_client_spec.rb
In our test, we will use a cassette called
all_forms
. We will run two tests. One to count the number of forms, and another to count the number of questions in the first form.
require 'spec_helper'
RSpec.describe FormulaeRuby::FormClient do
let(:form_client) { FormulaeRuby::FormClient.new(application_id: 1) }
describe '#all' do
it 'checks all the forms we have' do
VCR.use_cassette('all_forms') do
response = form_client.all
expect(response.count).to eq 68
first_form = response[0]
expect(first_form.questions.count).to eq 7
end
end
end
end
Let's see how our fixture looks like.
vim test/fixtures/all_forms.yml
Our API is running, so it gets the JSON from our API.
Let's go back to our test, and make a test for our find method.
describe '#find' do
it 'returns a form by a specific id' do
VCR.use_cassette('specific_form') do
response = form_client.find(1)
expect(response.questions.count).to eq 7
expect(response.application_id).to eq 1
expect(response.respond_to?(:application_id)).to be_truthy
expect(response.respond_to?(:questions)).to be_truthy
expect(response.respond_to?(:sections)).to be_truthy
end
end
end
The method find returns a form. So, we will check the quantity of questions. We will also check the keys.
Let's run our test suite, and see if everything is ok. It passes!
We can also see the fixture it has created.
Summary
Today we saw how to test our gem, make model tests, and test HTTP requests. Tomorrow, we will see how to deploy our application.
Comments for Testing HTTP Requests with VCR