开发者

In Rails controller tests, Is there a way to simulate a specific remote IP?

开发者 https://www.devze.com 2022-12-16 16:28 出处:网络
Some functionality in my app works differently depending on the client\'s IP address. Is the开发者_JAVA百科re a way to test that in Rails functional tests? I\'m using Test::Unit and Shoulda.You can do

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


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


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.


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.


Using gem "mocha" you can do:

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

精彩评论

暂无评论...
验证码 换一张
取 消