Rails中Stub控制器方法如何使返回的代码块被正常执行
问题根因
你当前写法不生效的核心原因是:stubs(:xxx).returns(xxx)的逻辑是将传入returns的参数直接作为目标方法的固定返回值,无论你传入的是lambda、proc还是普通值,都不会自动执行可执行对象内部的逻辑,所以会直接返回lambda对象本身。
正确实现方式
Mocha(Rails测试默认搭配的Stub库)的stubs方法支持直接传入代码块,当被stub的方法被调用时,会实际执行块内的逻辑,块的返回值就是方法的返回值。
直接写块逻辑(最常用)
不需要提前封装lambda,直接把要执行的逻辑写在stubs的块里即可:
MyController.any_instance.stubs(:my_method) do puts "Hey, I'm the new method!" redirect_to login_path end
复用已定义的lambda/proc
如果你确实需要提前把逻辑封装成可复用的lambda,不要把lambda直接传给returns,而是在stub的块内主动调用lambda:
new_method = lambda do puts "Hey, I'm the new method!" redirect_to login_path end MyController.any_instance.stubs(:my_method) { new_method.call }
补充说明
- 如果被stub的原方法需要接收参数,块也可以正常接收透传的参数,比如原方法签名为
my_method(user_id, path),块可以写成do |user_id, path|,参数顺序和原方法保持一致即可。 - 其他常用Mock库(比如RSpec Mocks)逻辑完全一致:要让stub的方法执行自定义逻辑,就给stub方法传代码块,不要把可执行对象传给返回值固定方法(比如
and_return/returns)。
内容的提问来源于stack exchange,提问作者Mirror318
相关产品推荐
相关产品推荐

