What is the WebMock way of doing it? If it is even possible, of course
- since your Readme states: "Always the last declared stub matching
the request will be applied"...
Another thing which seems to be missing in WebMock right now, is the
ability to stub whole response from file, not just body (as FakeWeb
does with its :response key). The reason for that, usually you have a
whole set of response stubs collected with "curl -i http://www.example.com/
> response_for_www.example.com". Now, it would be much easier to use
WebMock as an (almost) drop-in replacement for FakeWeb if you are able
to re-use these stub files. Instead of trying to split them all into
body and headers and manually set headers/status in stub_request, it's
much better to be able to say:
stub_request(:any, "www.example.com").to_return(:response => "/
path/to/your/stub/file")
Other than that, WebMock looks like a really great replacement for
FakeWeb with added functionality (like setting expectations for
request body and query params that's not possible currently with
fakeweb_matcher).
On Jan 18, 4:54 pm, Bartosz Blimke <bartosz.bli...@gmail.com> wrote:
> Hi,
>
> There is no way to stub identical request to respond with a sequence of
> responses in WebMock currently.
>
> This could be easily implemented i.e. by passing an array of response hashes
> to the to_return() method.
> The only problem is - how should WebMock behave after the last response was
> returned?
> Would it be ok if it returned the last response from a sequence infinitely?
>
> Let me know if you have any thought.
>
> Bartosz
>
> 2010/1/18 Arvicco <arvitall...@gmail.com>
Proposed interface for curl-gathered responses looks good to me,
indeed in makes sense when you're providing the whole response
(either from file or from string).
Regarding syntax for multiple responses, I totally understand your
desire
to provide fluent interfaces. However it will be much more difficult
to stub
multiple responses programmatically with this approach. Instead of
pushing all the necessary response hashes into array (adding :times
key as necessary) and then stubbing the whole set of responses in
one concise sentence, now you'll have to.. do what? construct a mile-
long
method chain or "times(n).then.to_return({...}).times(m).then.to_return
(..." ?
While improving readability somewhat in case of short response chains
(2-3 responses) in will become so unwieldy with longer response
chains... :(
You have noticed another problem with such interface("what should be
returned
as the 6th response?") resulting from :times directive not being part
of response
hash, but rather a separate member of method chain.
On Jan 20, 2:27 am, Bartosz Blimke <bartosz.bli...@gmail.com> wrote:
> I'm planning to add multiple responses with the following syntax:
>
> stub_request(:any, "www.example.com").to_return({ :body => "abc"}, { :body
> => "def" }).then.to_return({ :body => "ghj" }).then.to_raise(Error)
>
> Is "times" functionality useful? If yes, then it could be possibly added
> with syntax like:
>
> stub_request(:any, "www.example.com").to_return({ :body =>
> "abc"}).times(5).then.to_return({ :body => "ghj" })
>
> the only problem is, what should be returned as the 6th response, for the
> following stub:
>
> stub_request(:any, "www.example.com").to_return({ :body => "abc"}, { :body
> => "def" }).times(5).then.to_return({ :body => "ghj" }) ?
>
> Replying responses recorded with curl sound like a useful feature. I would
> add support using the following syntax:
>
> curl -ihttp://www.example.com/> response_for_www.example.com
>
> stub_request(:any, "www.example.com").to_return(File.new("
> response_for_www.example.com"))
>
> and
>
> response = File.new("response_for_www.example.com").read
> stub_request(:any, "www.example.com").to_return(response)
>
> Bartosz
>
> 2010/1/18 Arvicco <arvitall...@gmail.com>
My use case, however, requires stubbing a long response chains to the
same
uri (with different request bodies). Array of hashes seems to work
best in this case...
At the same time, I understand value of fluent interface for short
response chains.
Well, maybe you shouldn't try to lump together these two different
use
cases, and make separate method in addition to #to_return that
specifically accepts array of hashes used for building responses?
Say, stub_request().with([]) - or some better name, I'm not really
good
at constructing fluent interfaces. ;)
On Jan 20, 12:50 pm, Bartosz Blimke <bartosz.bli...@gmail.com> wrote:
> I would suspect that rarely anyone would use long chains (but I may be
> mistaken). I usually stub requests with a single response, but your specific
> case can be different. I do agree that fluent interfaces can significantly
> reduce readability if chains are too long.
> One thing I don't like, is mixing :times attribute in the response with
> other response specific attributs. While :body and :headers are obviously
> part of the response model, :times is not.
>
> Another problem is, how to define a stub that first returns response and on
> the next request raises exception. It's easy with
> to_return(...).then.to_raise(...). I again don't like the idea of mixing
> :exception attribute inside response, where it doesn't seem to belong.
>
> Ant thoughts?
>
> Bartosz
>
> 2010/1/20 Arvicco <arvitall...@gmail.com>
What we want to do is re-use the same uri, but offer multiple bodies/headers to match to multiple responses.
stub_uri(:uri => "", :request_mappings => [{:body => "MY SOAP REQUEST", :headers => "MY SOAP ACTION} => {:body => "MY SOAP RESPONSE", :status => 200, :headers => "MY SOAP RESPONSE HEADERS}, ...])
Niels
I just pushed new feature to master, pulled from Sergio Gill's fork.
It allows matching requests using a block provided. I think it could
be useful for matching complex SOAP requests.
i.e.
stub_http_request(:get, "www.example.com").with { |request|
request.body == "wadus" }
request(:get, "www.example.com").with { |req| req.body ==
"wadus" }.should have_been_made
Bartosz
Looked into new version you pushed, seems to be even cooler than the
previous one. Seems like it'll help you to write really expressive
specs...
A bit confused about your suggestion for stub_uri wrapper though... :(
Your README says this:
----
Always the last declared stub matching the request will be applied
i.e:
stub_request(:get, "www.example.com").to_return(:body =>
"abc")
stub_request(:get, "www.example.com").to_return(:body =>
"def")
Net::HTTP.get('www.example.com', '/') # ====> "def"
----
This seems to imply that stubbing multiple request_mappings via
stub_request
is not an option, as the last declared stub will be always returned..
Is this not
the case, or am I missing something here?
Also, it would be interesting to see how expectations on requests
sequence could
be set... Is there some way to set expectations for a specific
(ordered) sequence
of requests? It seems that currently there is no way to make following
expectations
order-sensitive, that is failing if order is def->abc instead of abc-
>def. Any suggestions?
WebMock.should have_requested(:get, "www.example.com").with(:body =>
"abc"})
WebMock.should have_requested(:get, "www.example.com").with(:body =>
"def"})
Arvicco
This seems to imply that stubbing multiple request_mappings via
stub_request
is not an option, as the last declared stub will be always returned..
Is this not
the case, or am I missing something here?
Also, it would be interesting to see how expectations on requests
sequence could
be set... Is there some way to set expectations for a specific
(ordered) sequence
of requests?
Regarding the example you provided, it looks like a bug. I will try to reproduce it and investigate it today.