我编写了一个使用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 liks 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,而无需实际访问互联网的所有开销?
感谢 -Josh
答案 0 :(得分:36)
使用Fakeweb删除互联网回复。
对于Google示例,首先转到网站并保存所需页面的html。在这种情况下,假设您通过浏览器或卷曲保存了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")
当您执行
的标准Mechanize调用时agent = Mechanize.New
page = agent.get("http://www.google.com/")
Fakeweb将返回您保存的页面,其中content_type标头设置为Mechanize认为它成功访问互联网的方式。确保设置了content_type标头,否则Mechanize会将响应视为Mechanize :: File而不是Mechanize :: Page。您可以通过在拔出网络连接的情况下在计算机上运行测试来测试它是否完全正常工作。
P.S。我问这个问题后6个月我回答了这个问题,因为这是谷歌的最高结果,但是没有答案。我花了30分钟自己搞清楚这一点并认为我会分享解决方案。
答案 1 :(得分:2)
如果您正在编写单元测试,那么您正在查看棒的错误结束,您不需要模拟google.com但是您应该模拟/存根Mechanize对象,即。创建一个mechanize对象,使用参数http://www.google.com在对象上调用get方法。是的,您确实需要通过访问页面来测试您正在执行的操作,您可以通过存根响应轻松完成该操作,然后进行所有测试。例如,如果您使用的是mocha,那么
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'
答案 2 :(得分:1)
如果您正在编写功能测试并且服务器不需要任何花哨的东西,您可以编写一个仅用于测试的小型HTTP服务器;测试代码配置被测代码以联系localhost上的小HTTP服务器:。
我建议WEBrick。建立一个HTTP服务器非常容易。