我有一个像这样定义的关注:
module Shared::Injectable
extend ActiveSupport::Concern
module ClassMethods
def injectable_attributes(attributes)
attributes.each do |atr|
define_method "injected_#{atr}" do
...
end
end
end
end
以及使用此类问题的各种模型:
Class MyThing < ActiveRecord::Base
include Shared::Injectable
...
injectable_attributes [:attr1, :attr2, :attr3, ...]
...
end
这可以按预期工作,并生成一组我可以在类的实例上调用的新方法:
my_thing_instance.injected_attr1
my_thing_instance.injected_attr2
my_thing_instance.injected_attr3
当我试图测试这个问题时,我的问题出现了。我想避免为使用该问题的每个模型手动创建测试,因为生成的函数都做同样的事情。相反,我认为我可以使用rspec&#39; s shared_example_for
并编写测试一次,然后使用rspec&#39; it_should_behave_like
在必要的模型中运行测试。这很好用,但是我在访问我传递给injectable_attributes
函数的参数时遇到了问题。
目前,我在共享规范中这样做:
shared_examples_for "injectable" do |item|
...
describe "some tests" do
attrs = item.methods.select{|m| m.to_s.include?("injected") and m.to_s.include?("published")}
attrs.each do |a|
it "should do something with #{a}" do
...
end
end
end
end
这很有效,但显然这是一种可怕的方式。是否有一种简单的方法可以通过类的实例或通过类本身访问传入injectable_attributes函数的值,而不是查看已在类实例上定义的方法?
答案 0 :(得分:1)
既然你说你想避免为每个使用关注点的模型手动创建测试,因为生成的函数都做同样的事情&#34;,那么单独测试模块的规范怎么样? ?
module Shared
module Injectable
extend ActiveSupport::Concern
module ClassMethods
def injectable_attributes(attributes)
attributes.each do |atr|
define_method "injected_#{atr}" do
# method content
end
end
end
end
end
end
RSpec.describe Shared::Injectable do
let(:injectable) do
Class.new do
include Shared::Injectable
injectable_attributes [:foo, :bar]
end.new
end
it 'creates an injected_* method for each injectable attribute' do
expect(injectable).to respond_to(:injected_foo)
expect(injectable).to respond_to(:injected_bar)
end
end
然后,作为一个选项,如果你想编写一般规范来测试一个对象是否真的具有可注入属性而不重复你在模块规范中得到的东西,你可以添加如下内容您的MyThing
规范文件:
RSpec.describe MyThing do
let(:my_thing) { MyThing.new }
it 'has injectable attributes' do
expect(my_thing).to be_kind_of(Shared::Injectable)
end
end
答案 1 :(得分:0)
尝试这样的事情怎么样:
class MyModel < ActiveRecord::Base
MODEL_ATTRIBUTES = [:attr1, :attr2, :attr3, ...]
end
it_behaves_like "injectable" do
let(:model_attributes) { MyModel::MODEL_ATTRIBUTES }
end
shared_examples "injectable" do
it "should validate all model attributes" do
model_attributes.each do |attr|
expect(subject.send("injected_#{attr}".to_sym)).to eq (SOMETHING IT SHOULD EQUAL)
end
end
end
它不会为每个属性创建单独的测试用例,但它们都应该为每个属性都有一个断言。这至少可以为你提供一些工作。