19

我写了一个小程序,使用 Mechanize 来遍历一个站点。

我想为它编写测试,但不希望它在我每次运行测试时实际登录网站。我想模拟互联网,这样当它进入某个站点时,它只会返回存储的结果。

这是一个小例子,假设我的代码的目的是从谷歌主页中提取链接,所以我编写了一个测试来确保我的代码找到的第一个链接有文本“图片”。我可能会写这样的东西:

require 'rubygems'
require 'mechanize'
require 'test/unit'

def my_code_to_find_links
  google = WWW::Mechanize.new.get('http://www.google.com')
  # ...
  # some code to figure out which links it wants
  # ...
  google.links
end

class TestGoogle < Test::Unit::TestCase
  def test_first_link_is_images
    assert_equal 'Images' , my_code_to_find_links.first.text
  end
end

如何模拟 google.com 以便我可以测试 my_code_to_find_links 而无需实际访问互联网的所有开销?

谢谢-乔什

4

4 回答 4

36

使用 Fakeweb 删除互联网响应。

对于 Google 示例,首先访问网站并保存所需页面的 html。在这种情况下,假设您通过浏览器或 curl 保存了 www.google.com。将 Fakeweb gem 添加到您的 test.rb 文件中

那么你的代码是

stream = File.read("saved_google_page.html")
FakeWeb.register_uri(:get, 
    "http://www.google.com", 
    :body => stream, 
    :content_type => "text/html")

当您执行标准的机械化呼叫时

agent = Mechanize.New
page = agent.get("http://www.google.com/")

Fakeweb 将返回您保存的带有 content_type 标头设置的页面,Mechanize 会认为它已成功访问 Internet。确保设置了 content_type 标头,否则 Mechanize 会将响应视为 Mechanize::File 而不是 Mechanize::Page。您可以通过在拔下网络连接的机器上运行测试来测试它是否完全正常工作。

ps 我在问这个问题 6 个月后回答这个问题,因为这是谷歌的最高结果,但没有得到回答。我自己花了 30 分钟来解决这个问题,并认为我会分享解决方案。

于 2010-07-21T00:00:45.223 回答
2

如果您正在编写功能测试并且服务器不需要任何花哨的东西,您可以编写一个只为测试运行的小型 HTTP 服务器;测试代码将被测代码配置为联系 localhost:<some_ephemeral_port> 上的小型 HTTP 服务器。

我推荐WEBrick。搭建一个 HTTP 服务器是一件轻而易举的事。

于 2010-01-28T04:28:10.230 回答
2

如果您正在编写单元测试,那么您正在寻找错误的一端,您不需要模拟 google.com,但您应该模拟/存根 Mechanize 对象,即。创建一个机械化对象,使用参数http://www.google.com在对象上调用 get 方法。是的,您确实需要通过访问页面来测试您正在对结果执行的操作,您可以通过存根响应轻松完成该页面,然后进行所有测试。例如,如果您使用的是摩卡咖啡,那么

mechanize = stub('WWW::Mechanize')
WWW::Mechanize.stubs(:new).returns(mechanize)
mechanize.stubs(:get).with('http://www.google.com').returns('What ever out put you are expecting so that you can test')

我认为您真的不需要测试您的请求是否发送到 google.com,因为这已经在 Mechanize gem 中进行了测试。

另一方面,如果您正在进行集成/黄瓜测试,那么您可以使用 sinatra 来伪造网站。Sinatra 使编写单页脚本并将该脚本作为网站运行变得非常容易。

编辑:

如果您不使用 mocha,那么您需要安装它并在测试中使用它

sudo gem install mocha

在你的测试中

require 'rubygems'
require 'mocha'
于 2010-01-28T07:36:44.577 回答
0

你也可以使用 Mechanize 的测试助手。一旦 Mechanize::TestCase 被加载,将不会在 mechanize 本身之外发出任何 HTTP 请求。所有请求都通过WEBrick servlet 处理。

创建一个夹具,要求测试用例,然后存根/模拟您的请求以返回:

require 'mechanize/test_case'

...

Mechanize::TestCase.new('http://google.com').html_page(html_fixture)

有关更多选项,请参见:https ://www.rubydoc.info/gems/mechanize/Mechanize/TestCase

于 2021-08-16T05:43:00.567 回答