RSpec 3 and why I `expect(you).to care`

RSpec 3 and why I `expect(you).to care`

Red Dot Ruby Conf 2014 talk about the decisions taken to create RSpec 3

D79fc498d7a5b2ce12180890247476f0?s=128

Jon Rowe

June 27, 2014
Tweet

Transcript

  1. 3.
  2. 4.
  3. 5.
  4. 8.
  5. 10.
  6. 11.
  7. 12.
  8. 15.

    class MyCustomObject def fuzzy? true end end ! describe do

    specify do my_model = MyCustomObject.new expect(my_model).to be_fuzzy end end
  9. 16.

    class MyCustomObject def fuzzy? true end end ! describe do

    specify do my_model = MyCustomObject.new my_model.should be_fuzzy end end
  10. 17.

    class MyCustomObject def fuzzy? true end end ! describe do

    specify do my_model = MyCustomObject.new expect(my_model).to be_fuzzy end end
  11. 18.

    describe do specify do expect { fail }.to raise_error !

    x = 1 expect { x += 1 }.to( change { x }.from(1).to(2) ) end end
  12. 29.
  13. 30.
  14. 34.

    class FuzzyProxy < BasicObject def initialize(target) @target = target end

    ! def fuzzy? true end ! def method_missing(*args, &block) @target.__send__(*args, &block) end end
  15. 35.

    describe FuzzyProxy do ! it 'is fuzzy' do instance =

    FuzzyProxy.new(:some_object) instance.should be_fuzzy end ! end
  16. 36.
  17. 38.
  18. 40.

    describe "SomeClass" do ! context "in some situation" do !

    it "will do something" do # ... end ! end ! end
  19. 41.

    RSpec.describe "SomeClass" do ! context "in some situation" do !

    it "will do something" do # ... end ! end ! end
  20. 44.
  21. 45.
  22. 47.

    class CustomFormatter # This registers the notifications this formatter #

    supports, and tells RSpec::Core::Formatters.register self, :example_sta ! def initialize(output) @output = output end ! def example_started(notification) @output << "example: “ @output << notification.example.description end ! end
  23. 53.

    require ‘rspec/its' ! describe do ! person = Struct.new(:first, :last)

    do def name [first, last].join(' ') end end ! subject(:bob) { person.new('Bob', 'Jones') } ! its(:name) { is_expected.to eq 'Bob Jones' } ! end
  24. 54.

    examples$ rspec lies_spec.rb --format doc ! ! name should eq

    "Bob Jones" ! Finished in 0.00094 seconds (files took 0.09512 1 example, 0 failures examples$
  25. 55.

    require ‘rspec/its' ! describe "#name" do ! person = Struct.new(:first,

    :last) do def name [first, last].join(' ') end end ! it "combines first and last" do bob = person.new('Bob', 'Jones') expect(bob.name).to eq 'Bob Jones' end ! end
  26. 56.

    examples$ rspec refactor_spec.rb --format doc ! ! name combines first

    and last ! Finished in 0.00084 seconds (files took 0.0084 1 example, 0 failures examples$
  27. 58.

    describe "verified doubles" do ! it "does something" do my_obj

    = instance_double( "MyObject", does: "cool things” ) expect(my_obj.does).to eq "cool things" end ! end
  28. 59.

    describe "verified doubles" do ! class MyObject end ! it

    "does something" do my_obj = instance_double( "MyObject", does: "cool things” ) expect(my_obj.does).to eq "cool things" end end
  29. 60.

    examples$ rspec verified_doubles_in_situ_spe F ! Failures: ! 1) verified doubles

    does something Failure/Error: my_obj = instance_double("M MyObject does not implement: does # ./verified_doubles_in_situ_spec.rb:7:in ! Finished in 0.00046 seconds (files took 0.07 1 example, 1 failure
  30. 61.

    describe "verified doubles" do ! class MyObject def does; true;

    end end ! it "does something" do my_obj = instance_double( "MyObject", does: "cool things” ) expect(my_obj.does).to eq "cool things" end end
  31. 62.

    describe "verified doubles" do ! class MyObject def does; true;

    end end ! it "does something" do my_obj = MyObject.new allow(my_obj).to receive(:other) { "things" } expect(my_obj.other).to eq "things" end end
  32. 64.

    describe "verified doubles" do ! class MyObject def does; true;

    end end ! RSpec.configuration.mock_with :rspec do |mocks| mocks.verify_partial_doubles = true end ! it "does something" do my_obj = MyObject.new allow(my_obj).to receive(:other) { "things" } expect(my_obj.other).to eq "things" end end
  33. 65.

    examples$ rspec verify_partial_doubles_spec. F ! Failures: ! 1) verified doubles

    does something Failure/Error: allow(my_obj).to receive(:o #<MyObject:0x00000101820288> does not implement: other # ./verify_partial_doubles_spec.rb:13:in ! Finished in 0.00562 seconds (files took 0.08 1 example, 1 failure
  34. 75.

    examples$ rspec broken_let_spec.rb F ! Failures: ! 1) Failure/Error: thing

    RuntimeError: let declaration `thing` accessed in a `before(:context)` hook at: examples/brok `let` and `subject` declarations are not intended to be called in a `before(:conte hook, as they exist to define state that is reset between each example, while
  35. 78.

    examples$ rspec before_all_stubs_broken_spec F ! Failures: ! 1) Failure/Error: allow(Object).to

    receive The use of doubles or partial doubles from rspec-mocks outside of the per-test lifecycle is not supported. # ./before_all_stubs_broken_spec.rb:4:in ! Finished in 0.00504 seconds (files took 0.07 1 example, 1 failure
  36. 80.
  37. 81.
  38. 82.

    describe do ! subject(:string) { "a string" } ! it

    { should be_a String } its(:length) { should == 8 } ! specify do string.should == "a string" end ! end
  39. 83.

    examples$ transpec Gathering the spec suite data... ! Converting examples/upgrade_spec.rb

    ! Summary: ! 2 conversions from: it { should ... } to: it { is_expected.to ... } 1 conversion from: obj.should to: expect(obj).to ! 6 conversions, 0 incompletes, 0 warnings, 0
  40. 84.

    describe do ! subject(:string) { "a string" } ! it

    { is_expected.to be_a String } ! describe '#length' do subject { super().length } it { is_expected.to eq(8) } end ! specify do expect(string).to eq("a string") end ! end
  41. 86.
  42. 87.