1

假设我有一些方法在某个对象上调用另一个方法:

def initialize
  @obj = SomeClass.new
end

def method
  @obj.another_method
end

如何使用 Rspec 和 进行测试.should_receive

4

2 回答 2

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 回答
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 回答