1

あるオブジェクトで別のメソッドを呼び出すメソッドがあるとします。

def initialize
  @obj = SomeClass.new
end

def method
  @obj.another_method
end

これを Rspec と でテストするにはどうすればよい.should_receiveですか?

4

2 に答える 2

1

obj をクラスに渡すことでそれを行うことができます。この手法は依存性注入と呼ばれます

http://sporto.github.io/blog/2013/09/25/simple-dependency-injection/

require "rspec"

class Foo
  def initialize(obj = SomeClass.new)
    @obj = obj
  end

  def method
    @obj.another_method
  end
end

describe Foo do
  describe "#method" do
    subject  { Foo.new(obj) }
    let(:obj){ mock }

    it "delegates to another_method" do
      obj.should_receive(:another_method).and_return("correct result")
      subject.method.should eq "correct result"
    end
  end
end

このようにすることもできますが、クラスの内部をテストするには非常に悪い方法です

require "rspec"

class Foo
  def initialize
    @obj = SomeClass.new
  end

  def method
    @obj.another_method
  end
end

describe Foo do
  describe "#method" do
    it "delegates to another_method" do
      subject.instance_variable_get(:@obj).should_receive(:another_method).and_return("correct result")
      subject.method.should eq "correct result"
    end
  end

  describe "#method" do
    it "delegates to another_method" do
      SomeClass.stub_chain(:new, :another_method).and_return("correct result")
      subject.method.should eq "correct result"
    end
  end

  describe "#method" do
    let(:obj) { mock(another_method: "correct result") }

    it "delegates to another_method" do
      SomeClass.stub(:new).and_return(obj)

      obj.should_receive(:another_method)
      subject.method.should eq "correct result"
    end
  end
end

私のコードでは、依存性注入を使用し、 #should_receive がまったくないことを意味するテスト出力のみを使用します

require "rspec"

class Foo
  attr_reader :obj

  def initialize(obj = Object.new)
    @obj = obj
  end

  def method
    obj.another_method
  end
end

describe Foo do
  describe "#method" do
    subject  { Foo.new(obj)}
    let(:obj){ mock }

    it "delegates to another_method" do
      obj.stub(:another_method).and_return("correct result")
      subject.method.should eq "correct result"
    end
  end
end
于 2013-10-19T17:39:26.587 に答える
1

他の回答によって提供される依存性注入が望ましいですが、既存のコードを考えると、次のようなことを行う必要があります。

describe "your class's method" do
  it "should invoke another method" do
    some_mock = double('SomeClass')
    SomeClass.should_receive(:new).and_return(some_mock)
    someMock.should_receive(:another_method).and_return('dummy_value')
    expect(YourClass.new.another_method).to eq('dummy_value')
  end
end

YourClass問題のクラスはどこですか。

更新: @Lewy にうなずいて戻り値のチェックを追加しました

于 2013-10-19T17:46:51.997 に答える