如何测试包含来自外部API的变量的assert_template

时间:2018-03-08 18:53:16

标签: ruby-on-rails rubygems integration-testing

我希望我的测试尽可能完整。 我正在尝试在用户的个人资料页面上使用assert_template,其中一些数据是使用Etsy Ruby Gem从Etsy API中提取的,但我似乎无法让它工作。

我在dev和prod中访问应用程序时数据显示正常。

我正在使用Webmock,并且非常感谢指点。

这是我得到的错误:

maayan@linux:~/apps/MyApp$ rails t
Started with run options --seed 18065

Run options: --seed 18065--=---=---=---=---=---=---=---=---=---=---=--] 0% Time: 00:00:00,  ETA: ??:??:??

# Running:

ERROR["test_login_with_valid_information_followed_by_logout", UsersLoginTest, 0.9254917360012769]
 test_login_with_valid_information_followed_by_logout#UsersLoginTest (0.93s)
Etsy::EtsyJSONInvalid:         Etsy::EtsyJSONInvalid: Etsy::EtsyJSONInvalid
            app/controllers/users_controller.rb:19:in `show'
            test/integration/users_login_test.rb:46:in `block in <class:UsersLoginTest>'

E 42/0: [                                                             ] 0% Time: 00:00:00,  ETA: ??:??:??

Error:
UsersLoginTest#test_login_with_valid_information_followed_by_logout:
Etsy::EtsyJSONInvalid: Etsy::EtsyJSONInvalid
    app/controllers/users_controller.rb:19:in `show'
    test/integration/users_login_test.rb:46:in `block in <class:UsersLoginTest>'


bin/rails test test/integration/users_login_test.rb:40

.  42/3: [====                                                         ] 7% Time: 00:00:01,  ETA: 00:00:1.  42/4: [=====                                                        ] 9% Time: 00:00:01,  ETA: 00:00:1...  42/7: [=========                                                   ] 16% Time: 00:00:01,  ETA: 00:00...  42/10: [=============                                              ] 23% Time: 00:00:01,  ETA: 00:00..  42/12: [================                                           ] 28% Time: 00:00:01,  ETA: 00:00:...  42/15: [====================                                       ] 35% Time: 00:00:01,  ETA: 00:00...  42/18: [========================                                   ] 42% Time: 00:00:01,  ETA: 00:00.  42/19: [==========================                                 ] 45% Time: 00:00:01,  ETA: 00:00:0.  42/20: [===========================                                ] 47% Time: 00:00:01,  ETA: 00:00:0.  42/21: [=============================                              ] 50% Time: 00:00:01,  ETA: 00:00:0..  42/23: [===============================                            ] 54% Time: 00:00:01,  ETA: 00:00:..  42/25: [==================================                         ] 59% Time: 00:00:01,  ETA: 00:00:.  42/26: [===================================                        ] 61% Time: 00:00:01,  ETA: 00:00:0.  42/27: [=====================================                      ] 64% Time: 00:00:01,  ETA: 00:00:0.  42/28: [======================================                     ] 66% Time: 00:00:01,  ETA: 00:00:0.  42/29: [========================================                   ] 69% Time: 00:00:01,  ETA: 00:00:0.  42/30: [=========================================                  ] 71% Time: 00:00:01,  ETA: 00:00:0.  42/31: [===========================================                ] 73% Time: 00:00:01,  ETA: 00:00:0.  42/32: [============================================               ] 76% Time: 00:00:01,  ETA: 00:00:0..  42/34: [===============================================            ] 80% Time: 00:00:01,  ETA: 00:00:..  42/36: [==================================================         ] 85% Time: 00:00:01,  ETA: 00:00:..  42/38: [=====================================================      ] 90% Time: 00:00:01,  ETA: 00:00:..  42/40: [========================================================   ] 95% Time: 00:00:01,  ETA: 00:00:..  42/42: [==========================================================] 100% Time: 00:00:01, Time: 00:00:01
.
Finished in 1.94843s
42 tests, 207 assertions, 0 failures, 1 errors, 0 skips

这是我的测试文件:

require 'test_helper'
require 'etsy'
# Tests user login
class UsersLoginTest < ActionDispatch::IntegrationTest
  def setup
    @user = users(:michael)
    stub_request(:get, "https://openapi.etsy.com/v2/shops/livingwatersbaby?api_key=g29bmrbb1xr4tfahjgqn58wh&fields=is_vacation,is_refusing_alchemy").
      with(  headers: {
        'Accept'=>'*/*',
        'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
        'User-Agent'=>'Ruby'
        }).
      to_return(status: 200, body: "", headers: {})
    stub_request(:get, "https://openapi.etsy.com/v2/users/?api_key=g29bmrbb1xr4tfahjgqn58wh").
      with(  headers: {
      'Accept'=>'*/*',
      'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
      'User-Agent'=>'Ruby'
      }).
    to_return(status: 200, body: "", headers: {})
    stub_request(:get, "https://openapi.etsy.com/v2/users/suellykirjner?api_key=g29bmrbb1xr4tfahjgqn58wh").
    with(  headers: {
      'Accept'=>'*/*',
      'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
      'User-Agent'=>'Ruby'
      }).
    to_return(status: 200, body: "", headers: {})
    end
  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email:    @user.email,
                                          password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
  end

这是我的装备:

michael:
  name: Michael Example
  email: michael@example.com
  password_digest: <%= User.digest('password') %>
  admin: true
  activated: true
  activated_at: Time.zone.now
  oauth_verifier: 'hidden'
  oauth_token: 'secret'
  request_secret: 'hidden'
  login_name: 'littlejane'

错误来自Etsy Gem,通常表示错误的身份验证令牌,但夹具的oauth_verifier,oauth_token和request_secret都是最新且正确的。 有没有更好的方法来存根外部API调用或我做错了什么? 非常感谢你。

1 个答案:

答案 0 :(得分:1)

看起来您的存根都返回空字符串作为结果:

stub_request(:get, "https://openapi.etsy.com/v2/shops/livingwatersbaby?api_key=g29bmrbb1xr4tfahjgqn58wh&fields=is_vacation,is_refusing_alchemy").
  with(  headers: {
    'Accept'=>'*/*',
    'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
    'User-Agent'=>'Ruby'
    }).
  to_return(status: 200, body: "", headers: {})

请注意body: ""

部分

""无效JSON,因此您收到EtsyJSONInvalid错误。

当我在做存根时,我常常做类似的事情:

response = JSON.dump({some: {valid: :hash}})

stub_request(:get, "https://openapi.etsy.com/v2/shops/livingwatersbaby?api_key=g29bmrbb1xr4tfahjgqn58wh&fields=is_vacation,is_refusing_alchemy").
  with(  headers: {
    'Accept'=>'*/*',
    'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
    'User-Agent'=>'Ruby'
    }).
  to_return(status: 200, body: response, headers: {})

而不是:

stub_request(:get, "https://openapi.etsy.com/v2/shops/livingwatersbaby?api_key=g29bmrbb1xr4tfahjgqn58wh&fields=is_vacation,is_refusing_alchemy").
  with(  headers: {
    'Accept'=>'*/*',
    'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
    'User-Agent'=>'Ruby'
    }).
  to_return(status: 200, body: JSON.dump({some: {valid: :hash}}), headers: {})

就我个人而言,我发现在设置与存根分开的响应时,视觉上的混乱程度稍微低一些。但是,这是一个问题或个人偏好。

事实上,我经常将存根移动到他们自己的方法中,例如:

require 'test_helper'
require 'etsy'
# Tests user login

class UsersLoginTest < ActionDispatch::IntegrationTest

  def setup
    @user = users(:michael)
    stub_foo
    stub_bar
    stub_baz
  end

  test "login with valid information followed by logout" do
    get login_path
    post login_path, params: { session: { email:    @user.email,
                                          password: 'password' } }
    assert is_logged_in?
    assert_redirected_to @user
    follow_redirect!
  end

  private 

    def stub_foo
      response = JSON.dump({some: {valid: :hash}})

      stub_request(:get, "https://openapi.etsy.com/v2/shops/livingwatersbaby?api_key=mY-4p1-k3y&fields=is_vacation,is_refusing_alchemy").
        with(headers: {
          'Accept'=>'*/*',
          'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
          'User-Agent'=>'Ruby'
          }).
        to_return(status: 200, body: response, headers: {})
    end

    def stub_bar
      response = JSON.dump({some_other: {valid: :hash}})

      stub_request(:get, "https://openapi.etsy.com/v2/users/?api_key=mY-4p1-k3y").
        with(headers: {
          'Accept'=>'*/*',
          'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
          'User-Agent'=>'Ruby'
        }).
        to_return(status: 200, body: response, headers: {})
    end

    def stub_baz
      response = JSON.dump({yet_another: {valid: :hash}})

      stub_request(:get, "https://openapi.etsy.com/v2/users/suellykirjner?api_key=mY-4p1-k3y").
        with(headers: {
          'Accept'=>'*/*',
          'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
          'User-Agent'=>'Ruby'
          }).
        to_return(status: 200, body: response, headers: {})
    end

end

同样,我发现它在视觉上更加混乱。