如何为 Rspec 中的特定参数存根方法
how to stub a method for a specific argument in Rspec
我正在尝试存根这样的方法:
allow(Flipper).to receive(:enabled?).with(:premium_plus_features_beta).and_return(false)
但是当它遇到不同的参数时 - 它会给我这样的错误:
#<Flipper (class)> received :enabled? with unexpected arguments
expected: (:premium_plus_features_beta)
got: (:non_advertiser_profile_amp, {:lawyer_id=>4469860})
Diff:
@@ -1,2 +1,2 @@
-[:premium_plus_features_beta]
+[:non_advertiser_profile_amp, {:lawyer_id=>4469860}]
我通常不会打这么多桩,但为什么当我明确告诉它参数时,为什么它会在不同的参数上出错?他们显然不一样。这只是一些语法问题吗?
编辑 1
Flipper.should_receive(:enabled?).and_call_original
Flipper.should_receive(:enabled?).with(:premium_plus_features_beta).and_return(false)
有效答案是:
allow(Flipper).to receive(:enabled?).and_call_original
allow(Flipper).to receive(:enabled?).with(:premium_plus_features_beta).and_return(false)
网上有一堆不好的信息哈哈
当使用特定参数对方法进行存根时,您只是用那些特定参数对特定方法调用进行存根。对该方法的所有其他调用都将失败并显示错误:
#<Foo (class)> received :bar with unexpected arguments
正如 OP 所发现的那样,这里的解决方案是首先使用 and_call_through
方法对对象的所有调用进行存根,然后使用您希望存根的特定参数对特定调用进行存根。
根据 OP 的回答,第一行存根所有对 Flipper 对象的调用并允许它们调用底层代码,第二行存根接收 :premium_plus_features_beta
和 [=34= 的调用] false
:
allow(Flipper).to receive(:enabled?).and_call_original
allow(Flipper).to receive(:enabled?).with(:beta).and_return(false)
此外,还有一点需要说明。 OP 问题中的代码使用了 OLD RSpec 期望语法。 OP 答案中的代码使用新的 RSpec 存根语法。所以,当代码这样说时:
Flipper.should_receive(:enabled?).and_call_original
Flipper.should_receive(:enabled?).with(:beta).and_return(false)
它在做什么:
expect(Flipper).to have_received(:enabled?).and_call_original
expect(Flipper).to have_received(:enabled?).with(:beta).and_return(false)
这与我认为 OP 真正想要做的完全不同:
before do
allow(Flipper).to receive(:enabled?).and_call_original
allow(Flipper).to receive(:enabled?).with(:beta).and_return(enabled?)
end
context "when the beta is disabled" do
let(:enabled?) { false }
it "hides the beta" do
...
end
end
context "when the beta is enabled" do
let(:enabled?) { true }
it "shows the beta" do
...
end
end
最后,对于那些好奇为什么 RSpec 更改语法的人...旧语法需要在 Object
上进行猴子补丁才能添加 should_receive
方法。我认为 RSpec 团队更喜欢新语法,因为它不再需要猴子补丁。
我正在尝试存根这样的方法:
allow(Flipper).to receive(:enabled?).with(:premium_plus_features_beta).and_return(false)
但是当它遇到不同的参数时 - 它会给我这样的错误:
#<Flipper (class)> received :enabled? with unexpected arguments
expected: (:premium_plus_features_beta)
got: (:non_advertiser_profile_amp, {:lawyer_id=>4469860})
Diff:
@@ -1,2 +1,2 @@
-[:premium_plus_features_beta]
+[:non_advertiser_profile_amp, {:lawyer_id=>4469860}]
我通常不会打这么多桩,但为什么当我明确告诉它参数时,为什么它会在不同的参数上出错?他们显然不一样。这只是一些语法问题吗?
编辑 1
Flipper.should_receive(:enabled?).and_call_original
Flipper.should_receive(:enabled?).with(:premium_plus_features_beta).and_return(false)
有效答案是:
allow(Flipper).to receive(:enabled?).and_call_original
allow(Flipper).to receive(:enabled?).with(:premium_plus_features_beta).and_return(false)
网上有一堆不好的信息哈哈
当使用特定参数对方法进行存根时,您只是用那些特定参数对特定方法调用进行存根。对该方法的所有其他调用都将失败并显示错误:
#<Foo (class)> received :bar with unexpected arguments
正如 OP 所发现的那样,这里的解决方案是首先使用 and_call_through
方法对对象的所有调用进行存根,然后使用您希望存根的特定参数对特定调用进行存根。
根据 OP 的回答,第一行存根所有对 Flipper 对象的调用并允许它们调用底层代码,第二行存根接收 :premium_plus_features_beta
和 [=34= 的调用] false
:
allow(Flipper).to receive(:enabled?).and_call_original
allow(Flipper).to receive(:enabled?).with(:beta).and_return(false)
此外,还有一点需要说明。 OP 问题中的代码使用了 OLD RSpec 期望语法。 OP 答案中的代码使用新的 RSpec 存根语法。所以,当代码这样说时:
Flipper.should_receive(:enabled?).and_call_original
Flipper.should_receive(:enabled?).with(:beta).and_return(false)
它在做什么:
expect(Flipper).to have_received(:enabled?).and_call_original
expect(Flipper).to have_received(:enabled?).with(:beta).and_return(false)
这与我认为 OP 真正想要做的完全不同:
before do
allow(Flipper).to receive(:enabled?).and_call_original
allow(Flipper).to receive(:enabled?).with(:beta).and_return(enabled?)
end
context "when the beta is disabled" do
let(:enabled?) { false }
it "hides the beta" do
...
end
end
context "when the beta is enabled" do
let(:enabled?) { true }
it "shows the beta" do
...
end
end
最后,对于那些好奇为什么 RSpec 更改语法的人...旧语法需要在 Object
上进行猴子补丁才能添加 should_receive
方法。我认为 RSpec 团队更喜欢新语法,因为它不再需要猴子补丁。