iT邦幫忙

2021 iThome 鐵人賽

DAY 21
0
自我挑戰組

Rails測試寫起乃!!!系列 第 21

Day21 測試寫起乃 - Webmock

在寫測試的時後,一定會有第三方服務或是會打向外部api的時候,如果不想讓他真的去打外部api怕速度過慢的等等問題就可以使用 webmock 。

webmock 可以偽裝 HTTP 來確保我們在測試時不會真的發出請求。

安裝 webmock

# add to your Gemfile
group :test do
    gem "webmock"
end
# spec_helper.rb

require 'webmock/rspec'
WebMock.disable_net_connect!(allow_localhost: true)

參考範例:

在還沒有禁用 api 之前會通過

    context "get github api" do
      it 'repo on GitHub' do
      uri = URI('https://api.github.com/repositories')

      response = Net::HTTP.get(uri)
        
      expect(response).to be_an_instance_of(String)
      end
    end

如果在測試之前加上

  before(:all) { WebMock.disable_net_connect! }
  after(:all) { WebMock.allow_net_connect! }
  
  context "get github api" do
    it 'repo on GitHub' do
    uri = URI('https://api.github.com/repositories')

    response = Net::HTTP.get(uri)

    expect(response).to be_an_instance_of(String)
    end
  end

此時會出現貼心的錯誤提示告訴你該如果撰寫

 Failure/Error: response = Net::HTTP.get(uri)

 WebMock::NetConnectNotAllowedError:
   Real HTTP connections are disabled. Unregistered request: GET https://api.github.com/repositories with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Host'=>'api.github.com', 'User-Agent'=>'Ruby'}

   You can stub this request with the following snippet:

   stub_request(:get, "https://api.github.com/repositories").
     with(
       headers: {
      'Accept'=>'*/*',
      'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
      'Host'=>'api.github.com',
      'User-Agent'=>'Ruby'
       }).
     to_return(status: 200, body: "", headers: {})

這時來修改一下

  context "github api" do
    it 'repo on GitHub' do
    uri = URI('https://api.github.com/repositories')

    stub_request(:get, uri).
    with(
      headers: {
      'Accept'=>'*/*',
      'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
      'Host'=>'api.github.com',
      'User-Agent'=>'Ruby'
      }).
    to_return(status: 200, body: "", headers: {})

    response = Net::HTTP.get(uri)

    expect(response).to be_an_instance_of(String)
    end
  end

這時確實已經將 api stub 了,且測試也會通過

參考來源:
WebMock
How to Stub External Services in Tests


上一篇
Day20 測試寫起乃 - $CHILD_STATUS
下一篇
Day22 測試寫起乃 - Sidekiq Testing
系列文
Rails測試寫起乃!!!30

尚未有邦友留言

立即登入留言