This is Devhints.io cheatsheets — a collection of cheatsheets I've written.

# RSpec

### Invoking tests

    rake -T spec      # List spec tasks

    rake spec         # Run all

    rake spec/models/mymodel_spec.rb
    rake spec/models/mymodel_spec.rb:27

## Writing tests

    describe "A User (in general)" do
      include UserSpecHelper

      subject { Person.new }

      let(:admin) { Person.new(role: :admin) }

      context "setter methods" do
        it "should do this" do
          pending "some other thing"

          expect(subject.name).to eq 'x'
        end
      end
    end

### Before/after

    before :each do
      # before all tests
    end

    before do
      # before this suite
    end

    after do
      # after this suite
    end

### Subjects

    subject { CheckingAccount.new }
    it { is_expected.to be_empty }

    # also names: subject(:account) { ... }

## Expectations

    target.should eq 1
    target.should_not eq 1

    expect(target).to eq 1
    expect(target).not_to eq 1

### Numeric

    expect(5).to be < 6
    expect(5).to == 5
    expect(5).to equal value
    expect(5).to be_between(1, 10)
    expect(5).to be_within(0.05).of value

### Comparison

    expect(x).to be value
    expect(x).to satisfy { |arg| ... }
    expect(x).to match /regexp/

### Predicate

    expect(x).to be_zero    # FixNum#zero?
    expect(x).to be_empty   # Array#empty?
    expect(x).to have_key   # Hash#has_key?

### Objects

    expect(obj).to be_an_instance_of MyClass
    expect(obj).to be_a_kind_of MyClass
    expect(obj).to respond_to :save!

### Control flow

    expect { user.save! }.to raise_error
    expect { user.save! }.to raise_error(ExceptionName, /msg/)
    expect { user.save! }.to throw :symbol

### Enumerables/arrays

    expect(list).to include(<object>)

    expect(list).to have(1).things
    expect(list).to have_at_least(2).things
    expect(list).to have_at_most(3).things

    expect(list).to have(2).errors_on(:field)

### Change

    expect { thing.approve! }.to \
      change(thing, :status)
      .from(Status::AWAITING_APPROVAL)
      .to(Status::APPROVED)

    expect { thing.destroy }.to \
      change(Thing, :count)
      .by(-1)

## Doubles

    book = double('book')
    book = instance_double('Book', pages: 250)

### Method stubs

    allow(die).to receive(:roll)
    allow(die).to receive(:roll) { 3 }
    allow_any_instance_of(Die).to receive(:roll)

    expect(die).to receive(:roll)
      .with(1)
      .with(1, true)
      .with(boolean)
      .with(anything)
      .with(any_args)
      .with(1, any_args)
      .with(no_args)
      .with(hash_including(a: 1))
      .with(hash_excluding(a: 1))
      .with(array_including(:a, :b))
      .with(array_excluding(:a, :b))
      .with(instance_of(Fixnum))
      .with(kind_of(Numeric))
      .with(<matcher>)

      .once
      .twice
      .exactly(n).times
      .at_least(:once)
      .at_least(:twice)
      .at_least(n).times
      .at_most(:once)
      .at_most(:twice)
      .at_most(n).times

https://relishapp.com/rspec/rspec-mocks/docs

## Spec helpers

    module UserSpecHelper
      def valid_user_attributes
        { :email => "joe@bloggs.com",
          :username => "joebloggs",
          :password => "abcdefg"}
      end
    end

    describe User do
      include UserSpecHelper

      ...
    end

Devhints.io cheatsheets is a collection of cheatsheets I've written over the years. Suggestions and corrections? Send them in. I'm Rico Sta. Cruz. Check out my Today I learned blog for more.