在Rails控制器测试中,有没有办法模拟特定的远程IP?

时间:2010-01-19 03:47:41

标签: ruby-on-rails unit-testing testing bdd shoulda

我的应用中的某些功能会根据客户端的IP地址而有所不同。有没有办法在Rails功能测试中测试?我正在使用Test :: Unit和Shoulda。

4 个答案:

答案 0 :(得分:31)

通过在控制器调用之前更改REMOTE_ADDR环境变量,您可以轻松地执行此操作而无需存根。这是一个虚构的控制器,如果用户的IP地址为1.2.3.4,则将用户重定向到主路径:

def index
  if request.remote_ip == '1.2.3.4'
    redirect_to root_path
    return
  end

  @articles = Article.all
end

以下是测试它是如何工作的方法:

def test_should_reject_ip_1_2_3_4
  @request.env['REMOTE_ADDR'] = '1.2.3.4'
  get :index
  assert_redirected_to root_path
end

您在控制器呼叫之前设置了远程IP,因此您可以在没有任何特殊插件或宝石的情况下伪造该数据。对于ItemsController:

,这是shoulda版本
context "with ip 1.2.3.4" do
  setup do
    @request.env['REMOTE_ADDR'] = '1.2.3.4'
    get :index
  end

  should_not_assign_to :items
  should_redirect_to("home"){home_path}
  should_not_set_the_flash
end

答案 1 :(得分:1)

接收控制器需要一种检测IP地址(或将其作为参数接收)的方法,您需要一种为测试注入特定IP地址的方法,或者只需将测试IP地址指定为参数。方法

如果考虑到您的应用程序的功能并不容易,那么您可以做的是让“自定义功能”适用于您家庭网络中的另一台计算机(如果有的话),并以这种方式测试应用程序。但这并没有真正解决“通过单元测试解决问题”的答案。

我可以问为什么您的应用会根据IP地址执行特定操作吗?也许还有另一种方式。

答案 2 :(得分:1)

您应该能够通过截断请求并返回request.remote_ip等于所需IP地址的模拟对象来实现此目的。

我会在FakeWeb寻求帮助。它可以让您轻松设置预期的请求/响应。查看Rails本身does these kinds of tests的方式也可能是有益的。

答案 3 :(得分:0)

使用gem“mocha”你可以做到:

test "should something" do
  request.expects(:remote_ip).returns("189.81.139.183")
  ...
end