MiniTest, as the name suggests, is a small and fast unit testing framework. Shipped with Ruby 1.9, MiniTest supports a complete suite of testing capabilities such as TDD, BDD, mocking, and benchmarking.
This quick reference aims to demonstrate MiniTest's main concepts and provide real world examples to get you acquainted quickly. Let's start with MiniTest::Spec.
MiniTest::Spec
Provides RSpec-like matchers and contexts right out of the box.
require 'minitest/autorun'
describe Hipster, "Demonstration of MiniTest" do
before do
@hipster = Hipster.new
end
after do
@hipster.destroy!
end
subject do
Array.new.tap do |attributes|
attributes << "silly hats"
attributes << "skinny jeans"
end
end
let(:list) { Array.new }
describe "when asked about the font" do
it "should be helvetica" do
@hipster.preferred_font.must_equal "helvetica"
end
end
describe "when asked about mainstream" do
it "won't be mainstream" do
@hipster.mainstream?.wont_equal true
end
end
end
Matchers (must | wont)
In most cases you can switch between must for positive expectations and wont
for negative expectations.
| Assertion | Examples |
must_be |
list.size.must_be :==, 0 |
must_be_close_to |
subject.size.must_be_close_to 1,1 |
must_be_empty |
list.must_be_empty |
must_be_instance_of |
list.must_be_instance_of Array |
must_be_kind_of |
list.must_be_kind_of Enumerable |
must_be_nil |
list.first.must_be_nil |
must_be_same_as |
subject.must_be_same_as subject |
must_be_silent |
proc { "no stdout or stderr" }.must_be_silent |
must_be_within_epsilon |
subject.size.must_be_within_epsilon 1,1 |
must_equal |
subject.size.must_equal 2 |
must_include |
subject.must_include "skinny jeans" |
must_match |
subject.first.must_match /silly/ |
must_output |
proc { print "#{subject.size}!" }.must_output "2!" |
must_respond_to |
subject.must_respond_to :count |
must_raise |
proc { subject.foo }.must_raise NoMethodError |
must_send |
subject.must_send [subject, :values_at, 0] |
must_throw |
proc { throw :done if subject.any? }.must_throw :done |
MiniTest::Unit::TestCase
Provides a rich set of assertions to make your tests clean and readable.
require 'minitest/autorun'
class TestHipster < MiniTest::Unit::TestCase
def setup
@hipster = Hipster.new
@list = Array.new
@subject = ["silly hats", "skinny jeans"]
end
def teardown
@hipster.destroy!
end
def test_for_helvetica_font
assert_equal "helvetica!", @hipster.preferred_font
end
def test_not_mainstream
refute @hipster.mainstream?
end
end
Assertions (assert | refute)
Toggle between assert for positive assertions and refute for negative assertions.
| Assertion | Example |
assert |
assert @subject.any?, "empty subjects" |
assert_block |
assert_block { @subject.any? } |
assert_empty |
assert_empty @list |
assert_equal |
assert_equal 2, @subject.size |
assert_in_delta |
assert_in_delta @subject.size, 1,1 |
assert_in_epsilon |
assert_in_epsilon @subject.size, 1, 1 |
assert_include |
assert_include "skinny jeans", @subject |
assert_instance_of |
assert_instance_of Array, @list |
assert_kind_of |
assert_kind_of Enumerable, @list |
assert_match |
assert_match @subject.first, /silly/ |
assert_nil |
assert_nil @list.first |
assert_operator |
assert_operator @list.size, :== , 0 |
assert_output |
assert_output("Size: 2") { print "Size: #{@subject.size}"} |
assert_raises |
assert_raises(NoMethodError) { @subject.foo } |
assert_respond_to |
assert_respond_to @subject, :count |
assert_same |
assert_same @subject, @subject, "It's the same object silly" |
assert_send |
assert_send [@subject, :values_at, 0] |
assert_silent |
assert_silent { "no stdout or stderr" } |
assert_throws |
assert_throws(:error,'is empty') {throw :error if @subject.any?} |
MiniTest::Mock
A simple and clean mock system. There two essential methods at our disposal:
expect and verify.
require 'minitest/autorun'
class Twipster
def initialize(twitter)
# A Ruby wrapper for the Twitter API
@twitter = twitter
end
def submit(tweet)
@twitter.update("#{tweet} #lolhipster")
end
end
describe Twipster, "Make every tweet a hipster tweet." do
before do
@twitter = MiniTest::Mock.new
@twipster = Twipster.new(@twitter)
end
it "should append a #lolhipster hashtag and update Twitter with our status" do
tweet = "Skyrim? Too mainstream."
@twitter.expect :update, true, ["#{tweet} #lolhipster"]
@twipster.submit(tweet)
assert @twitter.verify # verifies tweet and hashtag was passed to `@twitter.update`
end
end
Resources
- MiniTest on Github
- MiniTest Rdoc
- Using MiniTest::Spec with Rails
- Ruby Inside: A MiniTest::Spec Tutorial: Elegant Spec-Style Testing That Comes With Ruby
I hope you found this quick guide valuable. Please let me know if you'd like to see anything else included and feel free to ask questions or give feedback in the comments section.