我正在写一些rspec来测试一些模块正确实现他们的行为。
该模块如下所示:
module Under::Test
def some_behaviour
end
end
我无法在RSpec中执行此操作:
describe Under::Test do
subject {Class.new{include described_class}.new}
在调用点#described_class
时,它无法再被解析,因为self是Class的一个实例,它没有#describe_class方法。所以我不得不重复自己:
subject {Class.new{include Under::Test}.new}
或者以与我的客户使用方式不同的方式在规范中使用它:
subject {Object.new.extend described_class}
这具有相同的最终效果,但我认为如果我要求我的客户include Under::Test
,那么测试应该看起来与它们如何使用它们一样接近可能的。
我可以使用closure属性来解决这个问题,但我想知道它是不是更好。这有代码味吗?
describe Under::Test do
subject {mudule = described_class;Class.new{include mudule}.new}
it 'has some behaviour' do
expect(subject.some_behaviour).to be
end
end
注意,我还在reddit的r / ruby中询问过,有人建议:
subject {Class.new.include(described_class).new}
这可能就是我的方式。
答案 0 :(得分:5)
如果您的最终目标是deadline
新创建的include
中的当前described_class
模块,那么以下解决方法如何?
Class
以下是在对象中包含模块方法的示例:
RSpec.describe NewModule do
let(:test_class) do
Class.new.tap do |klass|
klass.include(described_class)
end
end
specify do
expect(test_class.ancestors).to include described_class # passes
end
end
请注意,在Ruby v2 +中,module NewModule
def identity
itself
end
end
RSpec.describe NewModule do
let(:one) do
1.tap do |obj|
obj.class.include(described_class)
end
end
specify do
expect(one.identity).to eq 1 # passes
end
end
的{{1}}方法不是include
。如果您使用的是旧版本,则必须使用Class
答案 1 :(得分:2)
我认为你的解决方案都很好,我更喜欢
Object.new.extend described_class
因其可读性和简洁性。如果您想使用Class.new
方法,我认为重复模块名称是可以的,正如Jared所说,可读性在这里比干燥更重要。