Ruby on rails 如何检查测试期间是否调用了API

Ruby on rails 如何检查测试期间是否调用了API,ruby-on-rails,ruby,Ruby On Rails,Ruby,我希望我们的应用程序能够与我们的微服务对话,通过API发送电子邮件 在测试中(在RSpec中),我想说: 做点什么 我希望微服务已被调用/未被调用 例如: it "asks the project to trigger all hooks" do expect(project).to receive(:execute_hooks).twice expect(project).to receive(:execute_services).twice expect(project).to

我希望我们的应用程序能够与我们的微服务对话,通过API发送电子邮件

在测试中(在RSpec中),我想说:

  • 做点什么
  • 我希望微服务已被调用/未被调用
  • 例如:

    it "asks the project to trigger all hooks" do
      expect(project).to receive(:execute_hooks).twice
      expect(project).to receive(:execute_services).twice
      expect(project).to receive(:update_merge_requests)
    
      PostReceive.new.perform(...)
    end
    
  • 创建用户
  • 我希望已经发送了欢迎电子邮件
  • 您需要使用,例如:

    it "asks the project to trigger all hooks" do
      expect(project).to receive(:execute_hooks).twice
      expect(project).to receive(:execute_services).twice
      expect(project).to receive(:update_merge_requests)
    
      PostReceive.new.perform(...)
    end
    

    关于邮件程序,请检查另一个

    从应用程序发送真正的HTTP请求可能有一些严重的缺点:

    • 由于连接问题而进行的抖动测试
    • 大大降低了测试套件的速度
    • 在第三方网站上达到API速率限制
    • 服务可能还不存在(仅提供相关文档)
    • 非确定性响应可能导致扑翼测试
    • API可能不提供沙盒或测试模式
    您还需要权衡每个应用程序的清晰边界与测试灵敏度。正确遵守应用程序边界意味着您只测试应用程序是否按照API的规定与合作者通信,并取消实际通信

    缺点当然是,在测试视力时,存根总是要付出代价的。您可能会错过API未按文档所述工作的bug,或者您只是在测试错误的东西

    Webmock例如,它允许您完全删除HTTP层。您可以设置外部调用的期望值并模拟返回值

    stub_request(:post, "api.example.com").to_return(status: 201)
    

    另一方面,VCR是一种中间路线,它允许您执行真正的HTTP请求,并将其记录到YML文件中,然后回放结果。后续运行速度更快且具有确定性。VCR比设置模拟响应要简单得多,但是您仍然需要设置初始状态并清除测试对外部服务的任何副作用

    VCR.use_cassette("synopsis") do
      response = Net::HTTP.get_response(URI('http://example.com'))
      expect(response.body).to match("Example domain")
    end
    
    这是一个从使用Flickr API的真实应用程序中提取的示例:

    RSpec.feature 'Importing photosets from flickr' do
    
      include JavascriptTestHelpers
    
      let(:user) { create(:admin, flickr_uid: 'xxx') }
    
      before { login_as user }
    
      let(:visit_new_photosets_path) do
        VCR.use_cassette('photosets_import') { visit new_photoset_path }
      end
    
      scenario 'When I create a photoset it should have the correct attributes', js: true do
        visit_new_photosets_path
        VCR.use_cassette('create_a_photoset') do
          click_button('Create Photoset', match: :first)
          wait_for_ajax
        end
        find('.photoset', match: :first).click
        expect(page).to have_content "Showcase"
        expect(page).to have_content "Like a greatest hits collection, but with snow."
        expect(page).to have_selector '.photo img', count: 10
      end
    end
    

    假设您正在尝试捕获和测试对应用程序外部API的HTTP调用,那么看看VCR编辑的消息期望和期望消息是不同的。