【问题标题】:Mocking methods in Puppet rspec testsPuppet rspec 测试中的模拟方法
【发布时间】:2014-04-18 16:00:28
【问题描述】:

我已经实现了一个自定义 Puppet 函数,它可以查询 Keystone 服务器以获取信息。定义此函数的模块包括一些辅助方法,它们执行查询 keystone 的实际工作。概括地说,结构如下所示:

def authenticate(auth_url, username, password)
...
end

def list_tenants(auth_url, token)
...
end

module Puppet::Parser::Functions
    newfunction(:lookup_tenant, :type => :rvalue) do |args|
    ...
    end
end

我想模拟出 authenticatelist_tenants 方法 在测试期间,以便我可以测试 Puppet 模块的其余部分 没有实际的 Keystone 服务器。

我以前没有使用过 Ruby 或 Rpsec,现在我 很难找到如何为这些提供存根的示例 内部方法。

到目前为止,我有一个存根 rspec 文件,它简单地验证了 功能:

require 'spec_helper'

describe 'lookup_tenant' do
    it "should exist" do
        Puppet::Parser::Functions.function("lookup_tenant").should == "function_lookup_tenant"
    end

    # This will fail because there is no keystone server.
    it "should fail" do
        should run.with_params(
            'http://127.0.0.1:35357/v2.0',
            'admin_user',
            'admin_password',
            'admin_tenant_name',
            'target_tenant_name'
       ).and_raise_error(KeystoneError)
    end
end

我希望能够从 authenticatelist_tenants 方法(甚至引发异常 从这些方法内部),以便我可以测试 lookup_tenant 不同故障场景下的函数。

【问题讨论】:

  • 您可以尝试使用 WebMock gem,它提供了以任何形式模拟和存根 http 调用...github.com/bblimke/webmock
  • webmock gem 很漂亮,完全解决了我的问题。您应该将其作为答案而不是评论。

标签: ruby unit-testing rspec puppet


【解决方案1】:

WebMock 可用于将 http 请求模拟为存根。这是github repo的链接:https://github.com/bblimke/webmock

【讨论】:

    【解决方案2】:

    对于以前没有见过webmock 的人,我想在这里留下一些信息,说明为什么它特别棒。

    所以,我的模块中有一些发出 http 请求的代码:

    url = URI.parse("#{auth_url}/tokens")
    req = Net::HTTP::Post.new url.path
    req['content-type'] = 'application/json'
    req.body = JSON.generate(post_args)
    
    begin
        res = Net::HTTP.start(url.host, url.port) {|http|
            http.request(req)
        }
    
        if res.code != '200'
            raise KeystoneError, "Failed to authenticate to Keystone server at #{auth_url} as user #{username}."
        end
    rescue Errno::ECONNREFUSED
        raise KeystoneError, "Failed to connect to Keystone server at #{auth_url}."
    end
    

    只需将require 添加到规范文件的开头即可:

    require `webmock`
    

    尝试打开连接将导致:

     WebMock::NetConnectNotAllowedError:
       Real HTTP connections are disabled. Unregistered request: POST http://127.0.0.1:35357/v2.0/tokens with body '{"auth":{"passwordCredentials":{"username":"admin_user","password":"admin_password"},"tenantName":"admin_tenant"}}' with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}
    
       You can stub this request with the following snippet:
    
       stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
         with(:body => "{\"auth\":{\"passwordCredentials\":{\"username\":\"admin_user\",\"password\":\"admin_password\"},\"tenantName\":\"admin_tenant\"}}",
              :headers => {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'Content-Type'=>'application/json', 'User-Agent'=>'Ruby'}).
         to_return(:status => 200, :body => "", :headers => {})
    

    这就是您删除 称呼。您可以根据需要使存根变得细化;我结束了 使用类似的东西:

    good_auth_request = { 
        'auth' => {
            'passwordCredentials' => {
                'username' => 'admin_user',
                'password' => 'admin_password',
            },
            'tenantName' => 'admin_tenant',
        }
    }
    
    auth_response = {
        'access' => {
            'token' => {
                'id' => 'TOKEN',
            }
        }
    }
    
    stub_request(:post, "http://127.0.0.1:35357/v2.0/tokens").
        with(:body => good_auth_request.to_json).
        to_return(:status => 200, :body => auth_response.to_json, :headers => {})
    

    现在我可以在没有 Keystone 服务器的情况下测试我的模块 可用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-06-13
      • 1970-01-01
      • 1970-01-01
      • 2016-07-20
      • 2017-03-27
      • 1970-01-01
      • 2011-02-17
      • 1970-01-01
      相关资源
      最近更新 更多