How to Use Rspec Expectations in Irb

How to use RSpec expectations in irb

You are close, but calling include on top-level you will be calling Module#include. To get around it you need to remove the original include method so that RSpec's include gets called instead.

First let's figure out where the system include comes from:

> method :include
=> #<Method: main.include>

Ok. It looks like it's defined in main. This is the Ruby top-level object. So let's rename and remove the original include:

> class << self; alias_method :inc, :include; remove_method :include; end

Now we can get down to business:

> require 'rspec'
> inc RSpec::Matchers
> [1,2,3].should include(1)
=> true

How can I use rspec expectations and matchers outside of Rspec?

When you include a module, it makes its methods available to instances of the class. Your test method is a singleton method (a "class method"), not an instance method, and thus will never have access to methods provided by mixed-in modules. To fix it, you can do:

class BF
include ::RSpec::Matchers

def test
expect(1).to eq(1)
end
end

BF.new.test

If you want the RSpec::Matchers methods to be available to singleton methods of BF, you can instead extend the module:

class BF
extend ::RSpec::Matchers

def self.test
expect(1).to eq(1)
end
end

BF.test

How to experiment with rspec from within irb

You can play around with RSpec test doubles in irb by requiring "rspec/mocks/standalone":

$ irb
> require 'rspec/mocks/standalone'
> b = double("book")
=> #<RSpec::Mocks::Mock:0x3fd88d0157e8 @name="book">

Using expect matcher in Rspec

If using Cucumber, you can simply include the 'rspec/expectations' in your env.rb file and then use the expected syntax in your step definitions.

env.rb:

 require 'rspec/expectations'

steps.rb:

 Then(/^I should be able to use rspec$/) do
expected = "this"
actual= "this"
expect(actual).to eql(expected)
end

My mistake was mistakingly testing this syntax in the ruby console. You cannot do that since Cucumber does some automagic stuff for you.

"When cucumber sees the Spec::Matchers and Spec::Expectations modules defined, it will implicitly include them in the World in which the steps are executed."

Launch irb while running RSpec tests for debugging purposes?

Use pry.

Simple, fast, with syntax highlighting. After install, you just need to write:

binding.pry

in your code to stop executing and display developer debugging console

After you fall in love with pry, there is also useful gem called 'pry-nav'

RSpec not_to does not show the correct result

The return value of false doesn't mean it failed, it just means 4 isn't nil. If it failed, it would have raised an error.

RSpec uses a NegativeOperatorMatcher class to test not_to expectations (source code here):

class NegativeOperatorMatcher < OperatorMatcher
def __delegate_operator(actual, operator, expected)
return false unless actual.__send__(operator, expected)
fail_with_message("expected not: #{operator} #{expected.inspect}\n got: #{operator.gsub(/./, ' ')} #{actual.inspect}")
end
end

So basically, it returns false unless the actual value equals the expected value, in which case it continues on to fail the spec (i.e. there's no situation where a negative matcher like not_to will ever return true).

is a one-line test like this possible in rspec

In irb:

require 'rspec-expectations'
include RSpec::Matchers

"bat".length.should eq(3)

How to test for stdout that is inside a .each iteration block, using rspec?

Todd's answer is fine and I'd strongly recommend you read it carefully: refactor your app in a way that UI (CLI in your case) is minimal and easy to test. But when you want full coverage you'd need to test that std output eventually.

The way you're using it now:

expect(initialize_program(1, 3)).to output("whatever").to_stdout

Means that initialize_program(1, 3) is evaluated immediately when the matcher is called, and it's too soon - it has to do it's magic(*) first, and then run your code. Try like this:

expect { initialize_program(1, 3) }.to output("whatever").to_stdout

Now, instead passing results of calling initialize_program(1, 3) into the matcher, you pass a block that "knows how" to call initialize_program(1, 3). So what the matcher does:

  1. saves the block for later
  2. does it magic to capture whatever goes to the STDOUT (see below)
  3. calls the block, calling the initialize_program(1, 3), capturing whatever was supposed to go to STDOUT
  4. compares it with what you've set up in your expectation (the output("whatever") part)

https://relishapp.com/rspec/rspec-expectations/docs/built-in-matchers/output-matcher

  • The mentioned magic is not that magical anyway:

https://github.com/rspec/rspec-expectations/blob/44d90f46a2654ffeab3ba65eff243039232802ce/lib/rspec/matchers/built_in/output.rb#L49
and
https://github.com/rspec/rspec-expectations/blob/44d90f46a2654ffeab3ba65eff243039232802ce/lib/rspec/matchers/built_in/output.rb#L141

It just creates StringIO, and replaces global var $stdout with it.



Related Topics



Leave a reply



Submit