0

我正在尝试在 Rpec 中为一个看起来像这样的类编写测试用例

class ABC
   def method_1( arg )
       #does something and return a value based on arg
   end

   def initialize
       @service = method_1( arg )
   end

   def getSomething_1
       return @service.get_seomthing_1
   end

   def getSomething_2
       return @service.get_seomthing_2
   end
end

现在我想用一个模拟对象启动@service 实例变量,以便我可以使用该模拟对象返回值,我可以根据这些值验证我的单元测试。

我试图做类似的事情

describe ABC do
    before(:each) do
       myObject = double()
       myObject.stub(:get_something_1).and_return("SomeValue")
       ABC.any_instance.stub(:method_1).and_return(myObject)
    end

   it "Checks the correctness of getSomething_1 method of class ABC" do
       @abc = ABC.new
       @abc.getSomething_1.should eql("SomeValue")
   end
end

现在,当我尝试运行测试时,@service 没有使用我想要的对象进行初始化。似乎 method_1 没有被定义的行为嘲笑。有人可以帮助我如何为我的模拟对象分配@service。

4

2 回答 2

0

你真的很接近,但看起来你在 ABC 的实例上错误地存根 :method_1 。您需要执行以下操作:

before(:each) do
  myObject = double(get_something_1: "SomeValue")
  ABC.any_instance().should_receive(:method_1).and_return(myObject)
end
于 2013-07-17T12:45:24.810 回答
0

你遇到的问题是你存根:method_1,它允许你控制它返回的内容,但同时短路它的行为。不幸的是,method_1返回的东西无关紧要,有趣的是它所做的——分配@service——这很有趣。

在没有看到你的类的实际界面和设计的情况下,我不能建议在这个分数上进行改进,但你至少可以通过@service.some_method用 attr_reader 替换对实例变量(即 )的引用来让你的期望正常工作:

class ABC
  attr_reader :service

  # ...

  def getSomething_1
    return service.get_seomthing_1
  end
end

然后在你的规范中:

describe ABC
  # ..

  before do
    ABC.any_instance(:service).and_return(myObject)
    # ...
  end

  it "Checks the correctness of getSomething_1 method of class ABC" do
    @abc = ABC.new("xyz")
    @abc.getSomething_1.should eql("SomeValue")
  end
end

在这种情况下,任何实例都将在调用ABC其属性时返回您的模拟,从而允许正确引用您的模拟。servicegetSomething_1

于 2013-07-17T12:50:16.287 回答