localjumperror no block given (yield)

落花浮王杯 提交于 2020-06-26 06:03:54

问题


When i ran my spec it shows

localjumperror no block given (yield)

My service file

service/update_many_post.rb

class UpdateManyPost

   def call
     posts.each do |post|
       response = UpdateAPost.new(post: post).call
       yield response
     end
   end

   private

   def posts
     Post.all
   end
end

/service/update_a_post.rb

class UpdateAPost
       def initialize(post:)
          @post = post
       end

       def call
          @post.title = "I am great"
          @post.save
       end
  end

This is how I call the service.

UpdateManyPost.new.call do |response|
   puts(response)
end

My rspec file

describe 'call' do

   let(:posts) { build(:post, 3) }

   subject { UpdateManyPost.new }

   it "has to update all the post" do
     expect { subject.call } 
   end
end

When I ran the spec it always shows that yield error, I need the yield for it to work, but I'm not sure how to fix the spec specifically


回答1:


Since you are not passing a block in your test

expect { subject.call } 

You will get a yield error because there is nothing to yield to.

You can solve this by passing a block in that call e.g.

expect { subject.call{|_|}} 

Or you can change your method definition to optionally call the block

def call
  posts.each do |post|
    response = UpdateAPost.new(post: post).call
    yield response if block_given? 
  end
end

This will check if a block was given to the "call" method and yield only if a block was given.

That being said your test does not test anything which will also cause issues because there is an expectation without any assertion (matcher). What are you trying to test?

You could test as

subject.call do |resp|
  expect(resp.saved_change_to_attribute?(:title)).to eq true
  expect(resp.title).to eq("I am great")
end

or

expect(Post.where.not(title: "I am great").exists?).to eq true
subject.call
expect(Post.where.not(title: "I am great").exists?).to eq false



回答2:


Please see how you run service UpdateManyPost in spec

subject.call

method "call" awaiting transfer to it lambda expression, but you don’t pass anything

provide transfer lambda to call in tests and everything works. As example:

     expect do
        subject.call do |it|
          # you do something with it 
        end
     end


来源:https://stackoverflow.com/questions/62463856/localjumperror-no-block-given-yield

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!