如果给出了一个块,我的任务是为以下简化方法编写rspec测试。没有给出阻止的情况已经过测试。
def make_something(name_id)
name = find_name_by_id(name_id)
if block_given? and name
yield(something)
name.save
end
name
end
测试是否有东西是没有问题的,但是如果调用name.save,我就会遇到问题。 我会这样做:
let!(:name) { create(:name) }
describe "when given a block" do
#works
it "yields something" do
expect { |b| subject.make_something(name.id, &b)}.to yield_with_args(something)
end
#1. try: doesn't work
it "saves the name" do
expect(name).to receive(:save)
subject.make_something(name.id) {}
end
#2. try: also doesn't work
it "saves the name" do
expect(name).to receive(:save)
subject.make_something(name.id) {|b|}
end
end
我很害羞,解决方案很明显,但我找不到它。
答案 0 :(得分:0)
我会尝试这样的事情:
let!(:name) { create(:name) }
describe "when given a block" do
before do
allow(subject).to receive(:find_name_by_id).with(name.id).and_return(name)
allow(name).to receive(:save).and_call_original
end
it "yields something" do
expect { |b|
subject.make_something(name.id, &b)
}.to yield_with_args(something)
end
it "saves the name" do
subject.make_something(name.id) {}
expect(name).to have_received(:save)
end
end
关键思想是将find_name_by_id
方法存根,以返回由name
创建的同一let!
实例。如果你不这样做,你的规范就会失败,因为你希望在save
的一个实例中调用name
,但它实际上是在另一个实例上调用的。