mirror of
https://github.com/lostisland/faraday.git
synced 2025-10-04 00:02:03 -04:00
Previously, the Faraday testing adapter compared the request body to the stubbed body just by calling `#==` if the stubbed body is present. Sometimes, I want to check the equality between request and stubbed body in more advanced ways. For example, there is a case that I want to check only the parts of the body are actually passed to Faraday instance like this: ```ruby stubs = Faraday::Adapter::Test::Stubs.new do |stub| stub.post('/foo', '{"name:"YK","created_at":"ANY STRING IS OK"}') { [200, {}, ''] } end connection.post('/foo', JSON.dump(name: 'YK', created_at: Time.now)) stubs.verify_stubbed_calls ``` In this case, it's difficult to make tests always pass with `"created_at"` because the value is dynamic. So, I came up with an idea to pass a proc as a stubbed value and compare bodies, inside the proc: ```ruby stubs = Faraday::Adapter::Test::Stubs.new do |stub| check = -> (request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'YK' } } stub.post('/foo', check) { [200, {}, ''] } end connection.post('/foo', JSON.dump(name: 'YK', created_at: Time.now)) stubs.verify_stubbed_calls ``` I believe this would be flexible but compatible with the previous behavior.
125 lines
3.6 KiB
Markdown
125 lines
3.6 KiB
Markdown
---
|
|
layout: documentation
|
|
title: "Testing"
|
|
permalink: /adapters/testing
|
|
hide: true
|
|
top_name: Adapters
|
|
top_link: ./
|
|
---
|
|
|
|
The built-in Faraday Test adapter lets you define stubbed HTTP requests. This can
|
|
be used to mock out network services in an application's unit tests.
|
|
|
|
The easiest way to do this is to create the stubbed requests when initializing
|
|
a `Faraday::Connection`. Stubbing a request by path yields a block with a
|
|
`Faraday::Env` object. The stub block expects an Array return value with three
|
|
values: an Integer HTTP status code, a Hash of key/value headers, and a
|
|
response body.
|
|
|
|
```ruby
|
|
conn = Faraday.new do |builder|
|
|
builder.adapter :test do |stub|
|
|
# block returns an array with 3 items:
|
|
# - Integer response status
|
|
# - Hash HTTP headers
|
|
# - String response body
|
|
stub.get('/ebi') do |env|
|
|
[
|
|
200,
|
|
{ 'Content-Type': 'text/plain', },
|
|
'shrimp'
|
|
]
|
|
end
|
|
|
|
# test exceptions too
|
|
stub.get('/boom') do
|
|
raise Faraday::ConnectionFailed
|
|
end
|
|
end
|
|
end
|
|
```
|
|
|
|
You can define the stubbed requests outside of the test adapter block:
|
|
|
|
```ruby
|
|
stubs = Faraday::Adapter::Test::Stubs.new do |stub|
|
|
stub.get('/tamago') { |env| [200, {}, 'egg'] }
|
|
end
|
|
```
|
|
|
|
This Stubs instance can be passed to a new Connection:
|
|
|
|
```ruby
|
|
conn = Faraday.new do |builder|
|
|
builder.adapter :test, stubs do |stub|
|
|
stub.get('/ebi') { |env| [ 200, {}, 'shrimp' ]}
|
|
end
|
|
end
|
|
```
|
|
|
|
It's also possible to stub additional requests after the connection has been
|
|
initialized. This is useful for testing.
|
|
|
|
```ruby
|
|
stubs.get('/uni') { |env| [ 200, {}, 'urchin' ]}
|
|
```
|
|
|
|
You can also stub the request body with a string or a proc.
|
|
It would be useful to pass a proc if it's OK only to check the parts of the request body are passed.
|
|
|
|
```ruby
|
|
stubs.post('/kohada', 'where=sea&temperature=24') { |env| [ 200, {}, 'spotted gizzard shad' ]}
|
|
stubs.post('/anago', -> (request_body) { JSON.parse(request_body).slice('name') == { 'name' => 'Wakamoto' } }) { |env| [200, {}, 'conger eel'] }
|
|
```
|
|
|
|
If you want to stub requests that exactly match a path, parameters, and headers,
|
|
`strict_mode` would be useful.
|
|
|
|
```ruby
|
|
stubs = Faraday::Adapter::Test::Stubs.new(strict_mode: true) do |stub|
|
|
stub.get('/ikura?nori=true', 'X-Soy-Sauce' => '5ml' ) { |env| [200, {}, 'ikura gunkan maki'] }
|
|
end
|
|
```
|
|
|
|
This stub expects the connection will be called like this:
|
|
|
|
```ruby
|
|
conn.get('/ikura', { nori: 'true' }, { 'X-Soy-Sauce' => '5ml' } )
|
|
```
|
|
|
|
If there are other parameters or headers included, the Faraday Test adapter
|
|
will raise `Faraday::Test::Stubs::NotFound`. It also raises the error
|
|
if the specified parameters (`nori`) or headers (`X-Soy-Sauce`) are omitted.
|
|
|
|
You can also enable `strict_mode` after initializing the connection.
|
|
In this case, all requests, including ones that have been already stubbed,
|
|
will be handled in a strict way.
|
|
|
|
```ruby
|
|
stubs.strict_mode = true
|
|
```
|
|
|
|
Finally, you can treat your stubs as mocks by verifying that all of the stubbed
|
|
calls were made. NOTE: this feature is still fairly experimental. It will not
|
|
verify the order or count of any stub.
|
|
|
|
```ruby
|
|
stubs.verify_stubbed_calls
|
|
```
|
|
|
|
After the test case is completed (possibly in an `after` hook), you should clear
|
|
the default connection to prevent it from being cached between different tests.
|
|
This allows for each test to have its own set of stubs
|
|
|
|
```ruby
|
|
Faraday.default_connection = nil
|
|
```
|
|
|
|
## Examples
|
|
|
|
Working [RSpec] and [test/unit] examples for a fictional JSON API client are
|
|
available.
|
|
|
|
[RSpec]: https://github.com/lostisland/faraday/blob/master/examples/client_spec.rb
|
|
[test/unit]: https://github.com/lostisland/faraday/blob/master/examples/client_test.rb
|