 <p>Created integration test test/integration/multiple_ip_test.rb</p> <pre><code>require 'test_helper' @@default_ip = "127.0.0.1" class ActionController::Request def remote_ip @@default_ip end end class MultipleIpTest &lt; ActionDispatch::IntegrationTest fixtures :all test "send email notification if login from different ip address" do post_via_redirect login_path, :user =&gt; {:username =&gt; "john", :password =&gt; "test"} assert_equal "/users/john", path reset! @@default_ip = "200.1.1.1" post_via_redirect login_path, :user =&gt; {:username =&gt; "john", :password =&gt; "test"} assert_equal "/users/john", path assert_equal 1, ActionMailer::Base.deliveries.size end end </code></pre> <p>Integration tests look a lot like functional tests, but there are some differences. You cannot use <code>@request</code> to change the origin IP address. This is why I had to open the <code>ActionController::Request</code> class and redefine the <code>remote_ip</code> method.</p> <p>Because the response to <code>post_via_redirect</code> is always 200, instead of using <code>assert_response :redirect</code> I use the URL to verify the user has logged in successfully.</p> <p>The call to <code>reset!</code> is necessary to start a new session.</p> <p>For an introduction on integration tests, check the <a href="http://guides.rubyonrails.org/testing.html#integration-testing" rel="nofollow">Rails Guides</a> on testing, unfortunately they do not mention the <code>reset!</code> method.</p>