如何在RSpec中包含模块/测试接口/测试角色?将POODR测试代码从Minitest转换为RSpec

如何在RSpec中包含模块/测试接口/测试角色?将POODR测试代码从Minitest转换为RSpec,rspec,module,minitest,Rspec,Module,Minitest,我想把Sandi Metz在“POODR”中的最终测试代码从Minitest翻译成RSpec。在第9章中,她检查“包含DiameterzableInterfaceTest”的任何对象是否具有“diameter”方法。在此,它检查DiameterDouble和Wheel是否都有“直径”方法: 但是模块中的所有“对象”组合都失败了。如果我使用“object”,它会说“未定义的局部变量或方法`object”。“对于@object”,它会说“预期的nil将响应:diameter。”对于“:object”

我想把Sandi Metz在“POODR”中的最终测试代码从Minitest翻译成RSpec。在第9章中,她检查“包含DiameterzableInterfaceTest”的任何对象是否具有“diameter”方法。在此,它检查DiameterDouble和Wheel是否都有“直径”方法:

但是模块中的所有“对象”组合都失败了。如果我使用“object”,它会说“未定义的局部变量或方法`object”。“对于@object”,它会说“预期的nil将响应:diameter。”对于“:object”,它会说“预期的:将响应的对象:diameter”

要在RSpec中包含该模块,唯一有效的方法是将“descripe”块更改为方法,如下所示。这迫使我为我检查的每个类添加一个it块,用于“has_diameter_method?”,这既荒谬又冗长:

module DiameterizableInterfaceTest
  def has_diameter_method?
    expect(@object).to respond_to(:diameter)
  end
end

class DiameterDouble
  def diameter
    10
  end
end

describe DiameterDouble do
  include DiameterizableInterfaceTest
  before do
    @object = DiameterDouble.new
  end

  it 'has diameter method' do
    has_diameter_method?
  end
end

describe Wheel do
  include DiameterizableInterfaceTest

  describe '#diameter' do
    before do
      @wheel = @object = Wheel.new(26, 1.5)
    end
    it 'calculates diameter' do
      expect(@wheel.diameter).to eq(29)
    end

    it 'has diameter method' do
      has_diameter_method?
    end
  end
end
如何在RSpec中的多类测试中包括模块,就像我在Minitest中所做的那样,而不添加这个额外的it块?在Minitest中,我可以为每个类添加一行“include diametrizableinterfacetest”检查。在RSpec中,需要再添加4行


以下是我想做的事情。在小型测试中很容易,但在RSpec中却不容易。

看看RSpec的“共享示例”:

我找到了答案!谢谢你,学校:

我的RSpec解决方案:

关键是使用
共享的\u示例
,这允许使用通用对象(“it”)。在测试中,我使用
it\u行为类似于
来检查共享示例中的所有行为。另外,对于Wheel,我需要添加
subject{Wheel}
,否则它会说
ArgumentError:arguments的数目错误(0代表2)


谢谢你,斯宾塞!我知道了!以下是我的答案:。谢谢你,学校:
module DiameterizableInterfaceTest
  describe 'object has diameter method' do
    it 'implements diameterizable interface' do
      expect(object).to respond_to(:diameter)
    end
  end
end

class DiameterDouble
  def diameter
    10
  end
end

describe DiameterDouble do
  include DiameterizableInterfaceTest
  let (:object) { DiameterDouble.new }
end
module DiameterizableInterfaceTest
  def has_diameter_method?
    expect(@object).to respond_to(:diameter)
  end
end

class DiameterDouble
  def diameter
    10
  end
end

describe DiameterDouble do
  include DiameterizableInterfaceTest
  before do
    @object = DiameterDouble.new
  end

  it 'has diameter method' do
    has_diameter_method?
  end
end

describe Wheel do
  include DiameterizableInterfaceTest

  describe '#diameter' do
    before do
      @wheel = @object = Wheel.new(26, 1.5)
    end
    it 'calculates diameter' do
      expect(@wheel.diameter).to eq(29)
    end

    it 'has diameter method' do
      has_diameter_method?
    end
  end
end
shared_examples 'Diameterizable' do
  it { should respond_to(:diameter) }
end

class DiameterDouble
  def diameter
    10
  end
end

describe DiameterDouble do
  it_behaves_like 'Diameterizable'
  let(:object) { DiameterDouble.new }
end

describe Wheel do
  it_behaves_like 'Diameterizable'
  let(:wheel) { Wheel.new(26, 1.5) }
  subject { wheel }

  it 'calculates diameter' do
    expect(wheel.diameter).to eq(29)
  end
end