【问题标题】:How do I mock an object in this case? no obvious way to replace object with mock在这种情况下如何模拟对象?没有明显的方法可以用模拟替换对象
【发布时间】:2011-02-01 23:14:02
【问题描述】:

假设我在 Store 的模型中有这个非常简单的方法:

  def geocode_address
      loc = Store.geocode(address)
    self.lat = loc.lat
    self.lng = loc.lng
  end

如果我想编写一些不受地理编码服务影响的测试脚本,这些脚本可能已关闭、有限制或取决于我的互联网连接,我该如何模拟地理编码服务?如果我可以将地理编码对象传递给该方法,那将很容易,但我不知道在这种情况下我该怎么做。

谢谢!
特里斯坦

【问题讨论】:

    标签: ruby-on-rails ruby unit-testing mocking rspec


    【解决方案1】:

    使用模拟和存根中内置的 rspecs,您可以执行以下操作:

    setup do
      @subject = MyClass.new
    end
    
    it 'handles geocoder success' do
      mock_geo = mock('result', :lat => 1, :lng => 1)
    
      Store.stub!(:geocode).and_return mock_geo
    
      @subject.geocode_address
    
      @subject.lat.should == mock_geo.lat
      @subject.lng.should == mock_geo.lng
    end
    
    
    it 'handles geocoder errors' do
      Store.stub!(:geocode).and_raise Exception
    
      @subject.geocode_address
    
      @subject.lat.should == _something_reasonable_
      @subject.lng.should == _something_reasonable_
    end
    

    【讨论】:

    • +1 很好的例子。我讨厌经常使用的将对象传递给类的做法,以便在测试中对其进行模拟。 OP 只需要确保他们在 Cucumber 之类的东西中测试真正的功能,重点是测试整个应用程序。
    【解决方案2】:

    使用 Double-R (RR) https://github.com/btakita/rr,很简单:

    test 'should mock the geocoding service' do
      store = Store.new
    
      mock_location = mock(Object.new)
      mock_location.lat{1.234}
      mock_location.lng{5.678}
      mock(Store).geocode.with_any_args{mock_location}
    
      store.geocode_address
      assert_equal 1.234, store.lat
      assert_equal 5.678, store.lng
    end
    

    【讨论】:

    • 应该是:mock(store).geocode.with_any_args{mock_location}
    • @ramn - 不,因为在 OP 的示例中,geocode 是 Store 的一个类方法。
    【解决方案3】:

    如果无法模拟服务,则表明其设计不佳。该服务应该与模型分开(无论Store 是什么)。您只需要重构为一个更加解耦的系统,这既可以让您模拟它,又可以让系统更易于维护。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-03-20
      • 2019-05-30
      相关资源
      最近更新 更多