I want to test a following method, which calls a module method with a block.
def test_target
MyModule.send do |payload|
payload.my_text = "payload text"
end
end
MyModule
's structure is like following.
module MyModule
class Payload
attr_accessor :my_text
def send
# do things with my_text
end
end
class << self
def send
payload = Payload.new
yield payload
payload.send
end
end
How can I test whether MyModule
receives send
method with a block, which assigns "payload text"
to payload.my_text
?
Currently I'm only testing expect(MyModule).to receive(:send).once
. I looked through and tried Rspec yield matchers but cannot get things done. (Maybe I've ben searching for wrong keywords..)
The easiest way is to insert a double as the yield
argument, which you can make an assertion on.
payload = Payload.new
allow(Payload).to receive(:new).and_return(payload)
test_target
expect(payload.my_text).to eq 'payload text'
Alternatively you could also use expect_any_instance_of
, but I'd always prefer to use a specific double instead.
I would mock MyModule
to yield another mock, that would allow speccing that my_text=
is called on the yielded object.
let(:payload) { instance_double('Payload') }
before do
allow(MyModule).to receive(:send).and_yield(payload)
allow(payload).to receive(:my_text=).and_return(nil)
end
# expectations
expect(MyModule).to have_received(:send).once
expect(payload).to have_received(:my_text=).with('payload text').once
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.