首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在rspec测试中检查WHERE子句

在rspec测试中检查WHERE子句
EN

Stack Overflow用户
提问于 2019-12-24 13:56:28
回答 3查看 557关注 0票数 0

我在rails中有一个命名作用域,我有一个名为Product的模型

代码语言:javascript
复制
class Product < ApplicationRecord
 scope :old_products, -> { where("tagged_with = ?","old") }
end

是否有任何主体遇到检查主题的过程,该主题使用活动记录中的where,并且可以检查命名范围实际持有的where子句是什么

在rspec spec/model/product_spec.rb中

代码语言:javascript
复制
describe Product do
  describe "checking scope clauses" do
  subject { Product.old_products }
    its(:where_clauses)   { should eq([
      "tagged_with = 'old'"
    ]) }
  end
  end
end

顺便说一句,我将rspec-2.89版本与rails-5版本一起使用,因此我们可以检查和验证where子句

EN

回答 3

Stack Overflow用户

发布于 2019-12-24 14:15:25

我个人认为检查一个作用域的返回SQL是不够的。我测试old_products的方式是:

代码语言:javascript
复制
describe Product do
  describe "scopes" do
    describe "old_products" do
      let!(:old_product) {Product.create(tagged_with: 'old')}
      let!(:not_old_product) {Product.create(tagged_with: 'sth_else')}
      subject { Product.old_products }

      it "returns the product(s) with tagged_with = old" do
        expect(subject).to eq([old_product])
      end
    end
  end
end

如果您仍然想检查返回查询,可以尝试一下:

代码语言:javascript
复制
it "..." do
  expect(subject.to_sql).to eq("SELECT \"products\".* FROM \"products\" WHERE \"products\".\"tagged_with\" = 'old'")
end
票数 3
EN

Stack Overflow用户

发布于 2019-12-28 05:24:34

代码语言:javascript
复制
# This is better, more readable syntax for scope declaration
class Product < ApplicationRecord
  scope :old_products, -> { where(tagged_with: 'old') }
end

# Something like this would work
describe Product do
  context 'scopes' do
    # Set up something that will always be excluded from the scopes
    let!(:product)     { create :product }
    let!(:scoped_list) { create :product, 3, tagged_with: tag }

    shared_examples_for 'returns scoped records' do
      # This should work with shoulda-matchers 
      # (https://github.com/thoughtbot/shoulda-matchers)
      # Could also not use subject and do something like:
      #   expect(
      #     described_class.send(scope_name.to_sym) 
      #   ).to contain_exactly(scoped_list)
      # and declare let(:scope_name) in your describe blocks
      it 'returns scoped products' do
        should contain_exactly(scoped_list)
      end
    end

    describe '.old_products' do
      subject(:old_products) { described_class.old_products }

      let(:tag) { 'old' }

      it_behaves_like 'returns scoped records'
    end

    describe '.other_scope' do
      subject(:other_scope) { described_class.other_scope }

      let(:tag) { 'other_tag' }

      it_behaves_like 'returns scoped records'
    end
  end
end

  • 测试实际的SQL没有任何价值--它是由Rails生成的;您要测试的是您的作用域是否返回了正确的对象
  • 在声明作用域测试块时,我会使用context而不是describe,因为您不是在描述类或实例方法
  • 使用单引号而不是双引号(除非您正在进行字符串插值) --它的性能更好

<>H110如果您在项目的早期,并且每个产品只有一个标记,我还会将tagged_with列重命名为tag

票数 0
EN

Stack Overflow用户

发布于 2020-02-05 20:08:49

代码语言:javascript
复制
describe Product do
  describe "checking scope clauses" do
  subject { Product.old_products }
    expect(subject.values[:where].instance_values['predicates'].to eq(["tagged_with = 'old'"])
  end
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59464425

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档