用mocha测试rails,mock HTTPResponse

上周六去了shanghai on rails聚会,其中一节是 张元一介绍关于mocha在rails测试中的应用

今天刚好项目测试代码中用到需要mock http response,刚好用到,要感谢张元一兄台

以前也写过信用卡支付网关以及soap服务器通讯相关的测试,用的办法是override掉http的request和response

比如下面这个典型场景,一个信用卡网关,我需要发送一个request请求,包含了请求的xml,网关处理信息后返回结果xml

需要测试的类Demo,包含一个实例方法request_to_services,request到服务器,服务器后执行返回response:

ruby 代码
  1. require 'uri'
  2. require 'net/http'
  3. class Demo
  4. def request_to_services
  5. uri = URI.parse("http://www.demo.com/services")
  6. request = Net::HTTP::Post.new(uri.path)
  7. request.body = "<xml>request data</xml>"
  8. http = Net::HTTP.new(uri.host, uri.port)
  9. response = http.request(request)
  10. raise unless response.is_a? Net::HTTPSuccess
  11. return response.body
  12. end
  13. end

测试方法这样写:

ruby 代码
  1. require 'demo'
  2. require 'test/unit'
  3. class TestDemo < Test::Unit::TestCase
  4. def test_request_to_services
  5. assert_equal "<xml>response data</xml>", Demo.new.request_to_services
  6. end
  7. end
  8. # 这里Override了ruby的HTTP request/response
  9. class Net::HTTP
  10. def request(request, body = nil, &block)
  11. Response.new("<xml>response data</xml>")
  12. end
  13. class Response < Net::HTTPSuccess
  14. attr_accessor :body
  15. def initialize(content)
  16. @body = content
  17. end
  18. end
  19. end


执行测试通过。我一直采用这个办法,非常简单,但是可以工作
这个方法有个缺点,Override的效果是全局的,也就是说在同一个时间只能模拟一种http的行为,缺乏灵活性
直到我碰到了mocha

ruby 代码
  1. require 'demo'
  2. require 'test/unit'
  3. require 'rubygems'
  4. require 'mocha'
  5. class TestDemo < Test::Unit::TestCase
  6. def test_request_to_services
  7. http = stub(:request => stub(:is_a? => true, :body => "<xml>response data</xml>"))
  8. Net::HTTP.expects(:new).times(1).returns(http)
  9. assert_equal "<xml>response data</xml>", Demo.new.request_to_services
  10. end
  11. def test_request_to_services_response_http_exception
  12. http = stub(:request => stub(:is_a? => false, :body => ""))
  13. Net::HTTP.expects(:new).times(1).returns(http)
  14. assert_raise RuntimeError do
  15. Demo.new.request_to_services
  16. end
  17. end
  18. end

用mocha来Mock对象非常灵活,下一步我将把所有的测试转到rspec上
借用hideto的说法:你应该试试 RSpec+ Mocha这道纯正的 墨西哥菜


TO BE CONTINUE!

你可能感兴趣的:(xml,.net,Ruby,Rails,rspec)