How to Use Ruby Minitest::Spec with Rails for API Integration Tests

How to use Ruby MiniTest::Spec with Rails for API integration tests?

Answering with what I've found so far in case it's helpful to other developers....

spec/api/items_spec.rb

require 'spec_helper'

class ItemsSpec < ActionDispatch::IntegrationTest

before do
@item = Factory.create(:item)
end

describe "items that are viewable by this user" do
it "responds with good json" do
get "/api/items.json"
response.success?.must_equal true
body.must_equal Item.all.to_json
items = JSON.parse(response.body)
items.any?{|x| x["name"] == @item.name}.must_equal true
end
end

end

spec/spec_helper.rb

ENV["RAILS_ENV"] = "test"
require File.expand_path('../../config/environment', __FILE__)
gem 'minitest'
require 'minitest/autorun'
require 'action_controller/test_case'
require 'capybara/rails'
require 'rails/test_help'
require 'miniskirt'
require 'factories'
require 'mocha'

# Support files
Dir["#{File.expand_path(File.dirname(__FILE__))}/support/*.rb"].each do |file|
require file
end

spec/factories/item.rb


Factory.define :item do |x|
x.name { "Foo" }
end

app/controllers/api/base_controller.rb

class Api::BaseController < ActionController::Base
respond_to :json
end

app/controllers/api/items_controller.rb

class Api::ItemsController < Api::BaseController
def index
respond_with(Item.all)
end
end

config/routes.rb

MyApp::Application.routes.draw do
namespace :api do
resources :items
end
end

Gemfile


group :development, :test do
gem 'capybara' # Integration test tool to simulate a user on a website.
gem 'capybara_minitest_spec' # MiniTest::Spec expectations for Capybara node matchers.
gem 'mocha' # Mocking and stubbing library for test doubles for Ruby.
gem 'minitest', '>= 3' # Ruby's core TDD, BDD, mocking, and benchmarking.
gem 'minitest-capybara' # Add Capybara driver switching parameters to minitest/spec.
gem 'minitest-matchers' # RSpec/Shoulda-style matchers for minitest.
gem 'minitest-metadata' # Annotate tests with metadata key-value pairs.
gem 'minitest-spec-rails' # Drop in MiniTest::Spec support for Rails 3.
gem 'miniskirt' # Factory creators to go with minitest.
gem 'ruby-prof' # Fast code profiler for Ruby with native C code.
end

How to configure minitest for integration tests using the unit style

My articles_integration_test.rb:

require 'test_helper'

class ArticlesIntegrationTest < IntegrationTest

def test_shows_article_title
article = Article.create!(title: 'Foo bar')
visit article_path(article)
assert page.has_content?('Foo bar')
end

end

My test_helper.rb:

ENV["RAILS_ENV"] = "test"
require File.expand_path("../../config/environment", __FILE__)
require "minitest/autorun"
require "capybara/rails"
require "active_support/testing/setup_and_teardown"

class IntegrationTest < MiniTest::Unit::TestCase
include Rails.application.routes.url_helpers
include Capybara::DSL
end

Minitest-Rails Spec-Style Tests by Default

Ok so @sonna had 90% of what I was looking for.

I ended up with help creating a .railsrc file with

-d postgresql
-m ~/.template.rb

And a template with:

# .template.rb
# Gems we've talked about in class, but which have absolutely nothing to do
# with setting up spec-style testing.
# Included here for convenience.
gem_group :development do
# Improve the error message you get in the browser
gem 'better_errors'

# Use pry for rails console
gem 'pry-rails'
end

# Add some extra minitest support
gem_group :test do
gem 'minitest-rails'
gem 'minitest-reporters'
end

# Add some code to some files to support spec-style testing
# For these injections, indentation matters!
inject_into_file 'config/application.rb', after: "class Application < Rails::Application\n" do
<<-'RUBY'
# Force new test files to be generated in the minitest-spec style
config.generators do |g|
g.test_framework :minitest, spec: true
end
RUBY
end

# Things to do after all the gems have been installed
after_bundle do
# Run rails generate minitest:install
generate "minitest:install", "--force"

# Add minitest reporters support. This must be run after
# rails generate minitest:install, because that command
# changes test/test_helper.rb
inject_into_file 'test/test_helper.rb', after: 'require "minitest/rails"' do
<<-'RUBY'

require "minitest/reporters" # for Colorized output

# For colorful output!
Minitest::Reporters.use!(
Minitest::Reporters::SpecReporter.new,
ENV,
Minitest.backtrace_filter
)
RUBY
end
end

This sets up my project with postgres for DB, and Minitest-rails using spec-style tests and includes minitest-reporters.

Use of Pagy rubygem in Rails tests with MiniTest

The pagy method is in the default configuration only available on the controller level, but not globally. You need to include Pagy::Backend to have it available in other classes.

I reckon the following might work:

include Pagy::Backend

test 'feed on Home page' do
get root_path

_pagy, microposts = pagy(@user.feed, page: 1)

microposts.each do |micropost|
assert_match CGI.escapeHTML(micropost.content), response.body
end
end

How to set up MiniTest?

This question is similar to How to run all tests with minitest?

Using Ruby 1.9.3 and Rake 0.9.2.2, given a directory layout like this:

Rakefile
lib/alpha.rb
spec/alpha_spec.rb

Here is what alpha_spec.rb might look like:

require 'minitest/spec'
require 'minitest/autorun' # arranges for minitest to run (in an exit handler, so it runs last)

require 'alpha'

describe 'Alpha' do
it 'greets you by name' do
Alpha.new.greet('Alice').must_equal('hello, Alice')
end
end

And here's Rakefile

require 'rake'
require 'rake/testtask'

Rake::TestTask.new do |t|
t.pattern = 'spec/**/*_spec.rb'
end

You can run

  • all tests: rake test
  • one test: ruby -Ilib spec/alpha_spec.rb

I don't know if using a spec_helper.rb with minitest is common or not. There does not appear to be a convenience method for loading one. Add this to the Rakefile:

require 'rake'
require 'rake/testtask'

Rake::TestTask.new do |t|
t.pattern = 'spec/**/*_spec.rb'
t.libs.push 'spec'
end

Then spec/spec_helper.rb can contain various redundant things:

require 'minitest/spec'
require 'minitest/autorun'
require 'alpha'

And spec/alpha_spec.rb replaces the redundant parts with:

require 'spec_helper'
  • all tests: rake test
  • one test: ruby -Ilib -Ispec spec/alpha_spec.rb

How to test integration with the Twilio API using Minitest

I ended up using the Ruby Gem VCR for the test. Turns outs that it's super easy to setup.

At the top of the test file, I added:

require 'vcr'

VCR.configure do |config|
config.cassette_library_dir = "test/vcr/cassettes"
config.hook_into :webmock
end

VCR lets the call go through the first time and records the response to a fixture file specified in the config.cassette_library_dir line above.

Then, in the actual test, I used VCR.use_cassette to record the successful call. I used a valid phone number to send to in order to verify it was working as well. You'll see a sample phone number in the test below. Be sure to change that if you use this example.

 test 'send message' do
VCR.use_cassette("send_sms") do
message = TwilioMessage.new.message('+18880007777')
assert_nil message.error_code
end
end

I found the RailsCast episode on VCR to be extremely helpful here.



Related Topics



Leave a reply



Submit