如何在RSpec中Stub ShopifyAPI::Theme.all请求?
嘿,我明白你要做的事儿了——在RSpec里Stub ShopifyAPI::Theme.all,让它返回能匹配role == "main"的静态数据对吧?这里有个关键点要注意:ShopifyAPI的Theme是ActiveResource模型,不是普通哈希,直接返回哈希的话,后面调用t.role会报错(因为哈希没有role方法)。得模拟出带有对应属性方法的Theme实例才行,我给你一步步来:
1. 构造模拟的Theme实例(替代纯哈希)
你可以用RSpec的double来轻量模拟Theme对象,只定义你需要用到的属性(比如role、id这些):
def test_main_theme double( "Theme", id: 2335539244, name: "Debut", created_at: "2017-12-22T18:13:24-05:00", updated_at: "2018-04-11T20:16:17-04:00", role: "main", theme_store_id: 796, previewable: true ) end # 如果需要模拟多个主题(比如一个main,一个其他角色),可以返回数组: def test_themes [ test_main_theme, double("Theme", role: "unpublished", id: 123456) ] end
2. Stub ShopifyAPI::Theme.all
接下来在测试里让ShopifyAPI::Theme.all返回你构造的模拟数组:
# 在你的测试用例的before块或者具体it块里 allow(ShopifyAPI::Theme).to receive(:all).and_return(test_themes)
3. 完整测试示例
假设你要测试的方法是这样的:
class ThemeService def self.get_main_theme ShopifyAPI::Theme.all.select { |t| t.role == "main" }.first end end
对应的RSpec测试可以这么写:
RSpec.describe ThemeService do describe ".get_main_theme" do let(:main_theme) do double( "Theme", id: 2335539244, name: "Debut", role: "main" ) end let(:unpublished_theme) { double("Theme", role: "unpublished") } before do allow(ShopifyAPI::Theme).to receive(:all).and_return([main_theme, unpublished_theme]) end it "returns the theme with role 'main'" do expect(described_class.get_main_theme).to eq(main_theme) end end end
为什么不能直接用哈希?
因为原代码里是调用t.role(方法调用),而哈希的话你得用t[:role],两者不兼容。用RSpec double或者模拟的Theme实例,才能让测试和原代码的调用方式保持一致。
如果你更倾向于用真实的ShopifyAPI::Theme实例(而不是double),也可以这么构造:
def test_main_theme theme = ShopifyAPI::Theme.new theme.id = 2335539244 theme.name = "Debut" theme.role = "main" # 其他属性按需赋值 theme end
这样Stub后也能正常工作,不过用double会更轻量,不需要初始化整个ActiveResource对象~
内容的提问来源于stack exchange,提问作者aldrien.h
相关产品推荐
相关产品推荐

