Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

what is the scope of 'let' in Rspec?

Tags:

let

ruby

rspec

I tried the following:

  describe "#check_recurring_and_send_message" do

    let(:schedule) {ScheduleKaya.new('test-client-id')}

    context "when it is 11AM and recurring event time is 10AM" do

      schedule.create_recurring_event('test-keyword', 'slack', 'day', '10 AM') 

      it "sends an SMS" do

      end

      it "set the next_occurrence to be for 10AM tomorrow" do 
        tomorrow = Chronic.parse("tomorrow at 10AM")
        expect(schedule.next_occurrence).to eq(tomorrow)
      end

    end

  end

I got an error around the scope:

`method_missing': `schedule` is not available on an example group (e.g. a `describe` or `context` block). It is only available from within individual examples (e.g. `it` blocks) or from constructs that run in the scope of an example (e.g. `before`, `let`, etc). (RSpec::Core::ExampleGroup::WrongScopeError)

Not only for this example but other times, I don't fully understand what the allowable scope is for let and for creating instances in Rspec.

What's the use case of let here versus just me creating using schedule = blah blah?

I guess I understand the literal intent of the error: I cannot use schedule in context only in it. But what's the right way then with this example to put stuff under describe, context, or it and in what way?

like image 504
Satchel Avatar asked Oct 18 '15 00:10

Satchel


People also ask

What is let in RSpec?

Use let to define a memoized helper method. The value will be cached. across multiple calls in the same example but not across examples. Note that let is lazy-evaluated: it is not evaluated until the first time. the method it defines is invoked.

What is the difference between let and let in RSpec?

You can use let! to force the method's invocation before each example. The difference between let, and let! is that let! is called in an implicit before block. So the result is evaluated and cached before the it block.

What is RSpec used for?

RSpec is a testing tool for Ruby, created for behavior-driven development (BDD). It is the most frequently used testing library for Ruby in production applications. Even though it has a very rich and powerful DSL (domain-specific language), at its core it is a simple tool which you can start using rather quickly.

What is example in RSpec?

The word it is another RSpec keyword which is used to define an “Example”. An example is basically a test or a test case. Again, like describe and context, it accepts both class name and string arguments and should be used with a block argument, designated with do/end.


1 Answers

Let is lazily evaluated which is nice when you want to share a variable across tests but only when the test needs it.

From the docs:

Use let to define a memoized helper method. The value will be cached across multiple calls in the same example but not across examples.

Note that let is lazy-evaluated: it is not evaluated until the first time the method it defines is invoked. You can use let! to force the method's invocation before each example.

By default, let is threadsafe, but you can configure it not to be by disabling config.threadsafe, which makes let perform a bit faster.

You're getting a method missing here because of this line:

schedule.create_recurring_event('test-keyword', 'slack', 'day', '10 AM') 

It seems you want that line to be evaluated before each it block in that context. You would just rewrite it like so:

describe "#check_recurring_and_send_message" do
  let(:schedule) {ScheduleKaya.new('test-client-id')}
  context "when it is 11AM and recurring event time is 10AM" do
    before(:each) do
      schedule.create_recurring_event('test-keyword', 'slack', 'day', '10 AM')
    end
    it "sends an SMS" do
    end
    it "set the next_occurrence to be for 10AM tomorrow" do
      tomorrow = Chronic.parse("tomorrow at 10AM")
      expect(schedule.next_occurrence).to eq(tomorrow)
    end
  end
end
like image 105
Anthony Avatar answered Oct 12 '22 09:10

Anthony