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

发布于 2024-08-18 11:49:55 字数 96 浏览 7 评论 0原文

我的应用程序中的某些功能的工作方式有所不同,具体取决于客户端的 IP 地址。有没有办法在 Rails 功能测试中测试这一点?我正在使用 Test::Unit 和 Shoulda。

Some functionality in my app works differently depending on the client's IP address. Is there a way to test that in Rails functional tests? I'm using Test::Unit and Shoulda.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

秋风の叶未落 2024-08-25 11:49:55

通过在控制器调用之前更改 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 的应该版本:

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

You can do this easily without stubbing, by changing the REMOTE_ADDR environment variable before your controller call. Here's a fictional controller that redirects the user to the home path if their ip address is 1.2.3.4:

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

  @articles = Article.all
end

Here's how you can test that it works:

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

You're setting the remote ip in advance of the controller call, so you're able to fake that data without any special plugins or gems. And here's the shoulda version, for ItemsController:

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
爱你不解释 2024-08-25 11:49:55

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

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

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

The receiving controller needs a method for detecting the IP address (or receiving it as a parameter), and you need a way to inject a specific IP address for your test, or just specifying the test IP address as a parameter to the method.

If that's not easy considering whatever your app does, what you could do is make the "custom functionality" apply to another computer on your home network, if you have one, and test the app that way. That doesn't really solve the "solve it through a unit test" answer though.

Can I ask why your app would perform a specific action depending on the IP address? Perhaps there's another way.

流星番茄 2024-08-25 11:49:55

您应该能够通过删除请求并返回一个 request.remote_ip 等于所需 IP 地址的模拟对象来完成此操作。

我会查看 FakeWeb 寻求帮助。它可以让您轻松设置预期的请求/响应。了解 Rails 本身的作用也可能会有所帮助这些类型的测试。

You should be able to accomplish this by stubbing out the requests and returning a mock object that has request.remote_ip equal to the desired IP address.

I'd look at FakeWeb for help on this. It lets you easily set up the expected requests/responses. It might also be instructive to look at how Rails itself does these kinds of tests.

悟红尘 2024-08-25 11:49:55

使用 gem“mocha”你可以这样做:

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

Using gem "mocha" you can do:

test "should something" do
  request.expects(:remote_ip).returns("189.81.139.183")
  ...
end
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文