5

假设我已经精炼了

module RefinedString
  refine String do
    def remove_latin_letters
      #code code code code
    end
  end
end

我在课堂演讲中使用它:

class Speech
  using RefinedString
  def initialize(text)
    @content = text.remove_latin_letters
  end
end

我已经在 RSpec 中编写了改进测试,现在我正在测试Speech class

describe Speech
  let(:text) { "ąńńóyińg" }

  it 'should call my refinement' do
    expect(text).to receive(:remove_latin_letters)
    Speech.new(text)
  end
end

但我明白了RSpec::Mocks::MockExpectationError: "ąńńóyińg" does not implement: remove_latin_letter

我不认为嘲笑它是一个好的解决方案(但我可能错了!在这里嘲笑解决方案吗?)

所以我尝试了

let(:text) { described_class::String.new("ąńńóyińg") } 但结果是一样的。

我不想using RefinedString在我的 RSpec 中显式调用(它应该自己解决,对吧?)

如何让 RSpec 了解我的改进方法?

4

1 回答 1

9

我们总是想测试行为,而不是实现。在我看来,细化通过被包含而不是拥有自己的行为来改变其他类的行为。用一个有点笨拙的类比,如果我们要测试病毒的繁殖行为,我们必须将它引入宿主细胞。我们感兴趣的是当病毒接管时宿主会发生什么(可以这么说)。

一种方法是构建带有和不带有细化的测试类,例如:

class TestClass
  attr_reader :content
  def initialize(text)
    @content = text.remove_latin_letters
  end
end

describe "when not using RefinedString" do
  it "raises an exception" do
    expect { TestClass.new("ąńńóyińg") }.to raise_error(NoMethodError)
  end
end

class RefinedTestClass
  using RefinedString
  attr_reader :content
   def initialize(text)
     @content = text.remove_latin_letters
  end
end

describe "when using RefinedString" do
  it "removes latin letters" do
    expect(RefinedTestClass.new("ąńńóyińg").content).to eq "ńńóń"
  end
end
于 2015-08-28T18:54:28.580 回答