Add Testing to Your Gem

There’s the old post about how to create a ruby gem. This post is focus on how to add testing to gem.
First, add rspec into your gem dependency. I like to use rspec as my testing framework. Here i also use webmock to mock my http request during spec testing.

your_gem.gemspec
1
2
3
4
5
Gem::Specification.new do |spec|
  ...
  spec.add_development_dependency 'rspec'
  spec.add_development_dependency 'webmock'
end

Create a rake task to run rspec. I create rspec.rake under {gem_root_folder}/tasks/. Set the default task to :spec then i can just type rake to run testing. In the meantime i set --color -f d to output result with color and document format.

rspec.rake
1
2
3
4
5
6
7
8
require 'rspec/core/rake_task'

desc 'Default: run specs.'
task :default => :spec

RSpec::Core::RakeTask.new do |task|
  task.rspec_opts = '--color -f d'
end

In order to exec our rspec.rake. Import all .rake file under tasks folder to Rakefile.

Rakefile
1
2
3
require "bundler/gem_tasks"

Dir.glob('tasks/**/*.rake').each(&method(:import))

Now we could start to write testing.
Create {gem_root_folder}/spec/ folder and spec_helper.rb under it.

spec_helper.rb
1
2
3
4
5
# require webmock/rspec to use webmock in rspec testing framework
require 'webmock/rspec'

# mvn_utils is the target class to be test
require 'mvn_utils'

Create mvn_utils_spec.rb under {gem_root_folder}/spec/ and require spec_helper. We could require all targets in spec_helper.rb and each spec.rb file just require spec_helper.

mvn_utils_spec.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
require 'spec_helper'
describe MvnUtils do

  let(:mvn_base) { "mvn.example.net/service/local/repositories/" }
  let(:header_hash) { {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'} }

  describe 'should find the latest version' do
    let(:response_xml) { "<metadata><groupId>a.b</groupId><artifactId>x.y</artifactId><versioning>" +
                         "<release>1.0.100</release><versions><version>1.0.98</version>" +
                         "<version>1.0.99</version></versions></versioning></metadata>" }

    it 'find_latest_version' do
      stub_request(:get, "http://#{mvn_base}a/b/x/y/maven-metadata.xml")
      .with(:headers => header_hash)
      .to_return(:status => 200, :body => response_xml, :headers => {})

      expect(MvnUtils.find_latest_version).to eq('1.0.100')
    end

end

In the above example, i test MvnUtils.find_latest_version and expect the value should be 1.0.100. This function will inovke http request to mvn server but i use stub request here to prevent real http connection. With stub request i could control the returned xml data.

Comments