【问题标题】:How to test a model instance method which makes a call to an external API如何测试调用外部 API 的模型实例方法
【发布时间】:2017-01-31 11:37:24
【问题描述】:

我无法理解在下面的案例中要测试什么以及如何测试。

我在地址模型上有以下实例方法

validate :address, on: [:create, :update]

def address
    check = CalendarEventLocationParsingWorker.new.perform("", self.structured, true )
    if check[:code] != 0
      errors.add(:base,"#{self.kind.capitalize} Address couldn't be analysed, please fill up as much fields as possible.")
    else
      self.lat = check[:coords]["lat"]
      self.lon = check[:coords]["lng"]
    end
  end

基本上它是一个在创建和更新挂钩上调用的方法,并使用第三方 API 检查地址是否有效。如何在不实际调用 3rd 方 api 而是模拟响应的情况下单独测试它?

我阅读了有关模拟和存根的信息,但我还没有完全理解它们。欢迎任何见解。使用 Rspec,应该是匹配器和工厂女孩。

【问题讨论】:

    标签: ruby-on-rails rspec shoulda


    【解决方案1】:

    使用 webmockvcr gem 来存根外部 api 响应

    一个 webmock 的例子:

    stub_request(:get, "your external api url")
      .to_return(code: 0, coords: { lat: 1, lng: 2 })
    
    # test your address method here
    

    使用vcr,您可以运行一次测试,它会实际调用外部api,将其响应记录到.yml 文件中,然后在以后的所有测试中重复使用。如果外部 api 响应发生变化,您只需删除 .yml 文件并记录新的示例响应即可。

    【讨论】:

    • 嘿,谢谢你,我可以不提出实际请求,即使一次也不行?
    • @PetrosKyriakou 是的,为此使用 webmock
    【解决方案2】:

    您可以在CalendarEventLocationParsingWorker 的任何实例上存根perform 方法以返回所需的值

    语法:

    allow_any_instance_of(Class).to receive(:method).and_return(:return_value)
    

    例如:

    allow_any_instance_of(CalendarEventLocationParsingWorker).to receive(:perform).and_return({code: 0})
    

    参考:Allow a message on any instance of a class

    【讨论】:

      猜你喜欢
      • 2018-02-24
      • 2016-07-19
      • 1970-01-01
      • 1970-01-01
      • 2018-02-28
      • 1970-01-01
      • 1970-01-01
      • 2021-03-12
      • 1970-01-01
      相关资源
      最近更新 更多