Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

added a method to remove stubs #211

Closed
wants to merge 3 commits into from

3 participants

@douglascamata

I needed to remove some specific stubs in one project and was unable to find this feature. If there's something wrong, please, let me know, so I can fix it ASAP.

@bblimke
Owner

Hi Douglas,

Thanks for this pull request.
Since you are first one who requested this feature in WebMock, could you please describe why do you need to remove stubs in your project?

I'm not sure if comparing to_s is the way to go.
You can possibly have multiple stubs with the same uri and method, but different to_s result due to query, body or headers.
Maybe best way would be if remove_stub used already implemented match behaviour.

I would also use remove_request_stub instead of remove_stub to avoid possible conflicts and make it obvious it's about requests and not any other stubs.

@douglascamata

Hi, thanks for the fast answer. I need this for the fake client to a storage web service that provides a uri to download stored files. The client gem should be able to be used in tests even without a real server running and we decided that the best way to do this is implementing a fake client instead of a fake server.

So, the problem is: this fake client is being used inside a Rails app and I need to fake the download of an already stored file using the fake client, but I don't have a real service or any fake web server running. Then, I need to stub a uri to return the file. That's ok. But the gem has a method to update files too, then I'd need to remove the old stub and stub the same uri again, but to return another body.

It might be a little confusing, did you understand?

Sure I can use the implemented match behaviour and change the method name, I made it in a rush and didn't have time to look more deeply for a better way to compare the stubs.

@douglascamata

Excuse me, but how I use, or where's the implemented match behaviour?

@bblimke
Owner

There is only matching behaviour between RequestStub (RequestPattern) and RequestSignature.

@douglascamata

Did it!

@bblimke
Owner

Thanks. Much better not to depend on to_s method.

In this case RequestSignature works as a matcher and RequestPattern works as a matched object.

I.e remove_request_stub(:get, "www.example.com") will match both stub_request(:get, /example/) and stub_request(:get, "www.example.com"). Is that desired?

@douglascamata

It won't make any difference for me. But if it does for you, I think I can fix it too.

@bblimke
Owner

For me id doesn't make any difference, since I don't need this feature, but I hope it's usefult to others :)
I just want to make sure it's the best approach, before adding it officially to webmock api.

Another option would be to use object identity (stub_request returns RequestStub) object,
so this can be solved in many different ways :)

@jmatraszek

any chance to get that merged?

@bblimke
Owner

@jmatraszek could you please explain how do you want to use this feature?

This would help to understand what's the best way to include it in webmock's api.

@bblimke
Owner

@jmatraszek @douglascamata Is this pull request still valid?

@jmatraszek I would like to get some feedback on how this feature is going to be used before adding it to webmock api.

Webmock always uses the last declared stub matching given request, so is there a need to remove old stubs from the stack?

@jmatraszek

Hi @bblimke,
sorry I didn't respond for such a long time -- I found a workaround and forgot about this issue.

I have a Device model. Every time I create device instance I issue a request to check if I am allowed to create that device. In specs I stub this request with success for most of my specs. There are also some specs in which I want to stub this request with failure. I do not want to break the rest of specs (they should not fail on creating device). In that case I cannot delete the last stub (failure), but I have to create another one with success. So instead of having only one stub in webmock's stack, I am having three of them.

That's not the big deal (and I have a workaround for it already), but it would be nice to be able to keep only one stub.

@douglascamata

@bblimke I'm not quite sure about what we did in project about this issue, it ended a few months ago. But I think we implemented a fake webserver for the tests.

@bblimke
Owner

@jmatraszek I added remove_request_stub method to the api (not released yet). It accepts stub object as an argument.

@bblimke bblimke closed this
@jmatraszek

thanks a lot! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Sep 12, 2012
  1. @douglascamata
Commits on Sep 13, 2012
  1. @douglascamata
Commits on Sep 17, 2012
  1. @douglascamata
This page is out of date. Refresh to see the latest.
View
5 lib/webmock/api.rb
@@ -7,6 +7,11 @@ def stub_request(method, uri)
register_request_stub(WebMock::RequestStub.new(method, uri))
end
+ def remove_request_stub(method, uri)
+ WebMock::StubRegistry.instance.
+ unregister_request_stub(WebMock::RequestSignature.new(method, uri))
+ end
+
alias_method :stub_http_request, :stub_request
def a_request(method, uri)
View
4 lib/webmock/stub_registry.rb
@@ -31,6 +31,10 @@ def register_global_stub(&block)
global_stubs.push stub
end
+ def unregister_request_stub(signature)
+ self.request_stubs.delete_if { |stub| stub.matches?(signature) }
+ end
+
def register_request_stub(stub)
request_stubs.insert(0, stub)
stub
View
32 spec/acceptance/shared/stubbing_requests.rb
@@ -444,4 +444,36 @@ def stub_non_globally
end
end
end
+
+ describe "removing stubs" do
+
+ before(:each) do
+ stub_request(:get, "www.example.com").to_return(:body => "abc")
+ end
+
+ it "should be able to remove a previously stubbed uri" do
+ WebMock.remove_request_stub(:get, "www.example.com")
+ lambda {
+ http_request(:get, "http://www.example.com/")
+ }.should raise_error(WebMock::NetConnectNotAllowedError, %r(Real HTTP connections are disabled. Unregistered request: GET http://www.example.com/))
+ end
+
+ it "should only remove the stub with the specified verb" do
+ stub_request(:post, "www.example.com")
+ WebMock.remove_request_stub(:get, "www.example.com")
+ lambda {
+ http_request(:get, "http://www.example.com/")
+ }.should raise_error(WebMock::NetConnectNotAllowedError, %r(Real HTTP connections are disabled. Unregistered request: GET http://www.example.com/))
+ http_request(:post, "http://www.example.com/", :body => "abc").status.should == "200"
+ end
+
+ it "should only remove the stub with the specified uri" do
+ stub_request(:get, "www.another.example.com")
+ WebMock.remove_request_stub(:get, "www.example.com")
+ lambda {
+ http_request(:get, "http://www.example.com/")
+ }.should raise_error(WebMock::NetConnectNotAllowedError, %r(Real HTTP connections are disabled. Unregistered request: GET http://www.example.com/))
+ http_request(:get, "http://www.another.example.com/").status.should == "200"
+ end
+ end
end
View
16 spec/unit/stub_registry_spec.rb
@@ -9,16 +9,28 @@
@request_stub = WebMock::RequestStub.new(:get, "www.example.com")
end
- describe "reset!" do
+ describe "cleaning the stubs" do
before(:each) do
WebMock::StubRegistry.instance.register_request_stub(@request_stub)
end
- it "should clean request stubs" do
+ it "should clean all request stubs" do
WebMock::StubRegistry.instance.registered_request?(@request_signature).should == @request_stub
WebMock::StubRegistry.instance.reset!
WebMock::StubRegistry.instance.registered_request?(@request_signature).should == nil
end
+
+ it "should clean only one stub" do
+ another_request_signature = WebMock::RequestSignature.new(:get, "www.another.example.com")
+ another_request_stub = WebMock::RequestStub.new(:get, "www.another.example.com")
+ WebMock::StubRegistry.instance.register_request_stub(another_request_stub)
+
+ WebMock::StubRegistry.instance.registered_request?(@request_signature).should == @request_stub
+ WebMock::StubRegistry.instance.unregister_request_stub(@request_signature)
+ WebMock::StubRegistry.instance.registered_request?(@request_signature).should == nil
+
+ WebMock::StubRegistry.instance.registered_request?(another_request_signature).should == another_request_stub
+ end
end
describe "registering and reporting registered requests" do
Something went wrong with that request. Please try again.