How to #let a JSON file in RSpec on Rails

How to #let a JSON file in RSpec on Rails



EDIT:



The solution seems to start with describe KayNein::Twitter do instead of RSpec.describe KayNein::Twitter do.


describe KayNein::Twitter do


RSpec.describe KayNein::Twitter do



Why is this the case?



Rails 5.2.1
Ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]



Original Question



I have a class that initializes with a JSON file:


module KayNein
class Twitter < Handler

def initialize(json_file)
@website_hash = JSON.parse(json_file)
end



And I'm trying to write an RSpec:


RSpec.describe KayNein::Twitter do
let (:json_file) File.read(PATH_TO_FILE)
context "Initialized" do
subject = KayNein::Twitter.new(json_file)
end
end



But RSpec gives me this error:


An error occurred while loading ./spec/app/kay_nein/sites/twitter_spec.rb.
Failure/Error: subject = KayNein::Twitter.new(json_file)
`json_file` 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).
# ./spec/app/kay_nein/sites/twitter_spec.rb:8:in `block (2 levels) in <top (required)>'
# ./spec/app/kay_nein/sites/twitter_spec.rb:7:in `block in <top (required)>'
# ./spec/app/kay_nein/sites/twitter_spec.rb:5:in `<top (required)>'



What am I doing wrong?



Even this gives me an error, so it has nothing to do with the file:


RSpec.describe KayNein::Twitter do
let (:json_file) "Hello world"
context "Initialized" do
subject = KayNein::Twitter.new(json_file)
end
end






have you defined: ` File.read(PATH_TO_FILE)`?

– BKSpurgeon
Sep 11 '18 at 1:09






also, does File.read return a value? I couldn't find it the documentation.

– BKSpurgeon
Sep 11 '18 at 1:11






@BKSpurgeon yes it is defined, I'm just not disclosing the file path here for the sake of privacy

– clockworkpc
Sep 11 '18 at 1:21






@BKSpurgeon yes, File.read returns a value, it reads it as a JSON file.

– clockworkpc
Sep 11 '18 at 1:23







are you pasting in the full file? is your test wrapped in a it "returns a file" do write your test here end?

– BKSpurgeon
Sep 11 '18 at 1:41



it "returns a file" do write your test here end




3 Answers
3



Can you try something like this ?


let(:file) File.read(File.join('spec', 'fixtures', 'public', filename))

describe "File" do
it "should be a file" do
expect(file).to be_a File
end

it "should initialize and read the contents"
initialize_file = KayNein::Twitter.new(file)
expect(response.body["key"]).to eq(..)
end
end






I think this inadvertantly helped me solve it. I removed "RSpec" from Rspec.describe and now I can #let.

– clockworkpc
Sep 11 '18 at 2:51


Rspec.describe


We have two ways to DRY up tests (before and let) that share an intersecting purpose, to create variables that are common across tests. For common variable instantiation, the Ruby community prefers let, and while before is often used to perform actions common across tests.

when you use the context you can initialize the let inside the context block like this, will work

describe KayNein::Twitter do
context "Initialized" do
let (:json_file) File.read(PATH_TO_FILE)
subject = KayNein::Twitter.new(json_file)
end
end

otherwise if you don't want to use context, can try this way

describe KayNein::Twitter do
let (:json_file) File.read(PATH_TO_FILE)
it "Initialized" do
subject = KayNein::Twitter.new(json_file)
end
end



You can think of let as defining accessors. And those accessors are available only inside example blocks it or specify.


let


it


specify



You are trying to use json_file (defined in let) inside a context. And this is exactly what the error message is trying to tell you:


json_file


context



json_file 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).


json_file


describe


context


it


before


let



You can fix it like this:


RSpec.describe KayNein::Twitter do
let (:json_file) File.read(PATH_TO_FILE)
context "Initialized" do
specify do # it instead of specify also works
subject = KayNein::Twitter.new(json_file)
expect(subject).not_to be_nil # this is just an example, not needed to
# get rid of the issue
end
end
end



or even better - define subject outside of example block (for reusability etc) like this:


RSpec.describe KayNein::Twitter do
let (:json_file) File.read(PATH_TO_FILE)
subject KayNein::Twitter.new(json_file)
context "Initialized" do
specify do # it instead of specify also works
expect(subject).not_to be_nil # this is just an example, not needed to
# get rid of the issue
end
end
end



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)